GIT 9c8e86195d75a1f4875e9ced083a015a99cec94e git+ssh://master.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git#ALL commit Author: John W. Linville Date: Tue Dec 4 17:24:35 2007 -0500 rt2x00: correct "skb_buff" typo Signed-off-by: John W. Linville Signed-off-by: Jeff Garzik commit 558f08ed31c6909d3c9ae5d6dbf81220ede4b54a Author: Grant Likely Date: Sat Dec 1 22:12:45 2007 -0700 gianfar driver: eliminate compiler warnings and unnecessary macros This patch eliminates the warning of unused return values when the driver registers it sysfs files. Now the driver will print an error if it is unable to register the sysfs files. It also eliminates the macros used to wrap the DEVICE_ATTR macro and the device_create_file function call. The macros don't reduce the number of lines of source code in the file and the name munging makes is so that cscope and friends don't see the references to the functions. It's better to just call the kernel API directly. While we're at it, the DEVICE_ATTR instances have been moved down to be grouped with the functions they depend on. Signed-off-by: Grant Likely Signed-off-by: Jeff Garzik commit 69ebd5521a45d3a16afd211eb497c368d8a46a8c Author: Matthias Mueller Date: Sun Dec 2 17:17:51 2007 -0500 rtl8187: Add USB ID for Sitecom WL-168 v1 001 Thanks to Matthias Mueller for reporting this device. Signed-off-by: Michael Wu Signed-off-by: John W. Linville commit e4128a54d790658ab265c915e5da9153ff74af97 Author: Andrea Merello Date: Sun Dec 2 17:17:51 2007 -0500 rtl8187: fix tx power reading CCK and OFDM power levels are stored in adjacent bytes, not nibbles. Signed-off-by: Michael Wu Signed-off-by: Andrea Merello Signed-off-by: John W. Linville commit fc2439c947e5714682a58f40b0bb0041174bbcc8 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:42 2007 +0200 iwlwifi: 802.11n add support to 8K A-MSDU Rx frames This patch give the iwlwifi the ability to support A-MSDU up to 8K Please notice - in order to work in 8K A-MSDU ucode support is needed, version 4.44.1.19 (soon to be published). 4K A-MSDU works in current ucode version as well. Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 6fe8f207906eeebf7a87cb8bccf5328676f72bc6 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:41 2007 +0200 iwlwifi: 802.11n comply HT rate scaling flows with mac80211 framework This patch conforms the rate scaling flows according to the new mac80211's HT framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 3be1ba0a41fac526bf4d408fcdc18f0dfd943490 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:40 2007 +0200 iwlwifi: 802.11n comply HT add station flow with mac80211 framework This patch conforms the addition of a new station to the iwlwifi station table according to the new mac80211's HT framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit a6239d7afe603c46d457e1ce7360db230f88906a Author: Ron Rindjunsky Date: Mon Nov 26 16:14:39 2007 +0200 iwlwifi: 802.11n comply HT self configuration flow with mac80211 framework This patch conforms HW configuration changes according to new mac80211's HT framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 0920c20fc94f43927612fc43e05bd016dd74ca56 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:38 2007 +0200 iwlwifi: 802.11n handling probe request HT IE This patch conforms the probe request's HT IE with the new structures used in iwlwifi HT. Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 8d2dd8215b99f6e1b56103534c09131a49789a49 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:37 2007 +0200 iwlwifi: 802.11n configuring hw_mode parameters to support HT in A/G This patch fills the mac80211's ieee80211_hw_mode structures with the needed 802.11n data needed for the new framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit f8d5e09463c6e72029ac46c71921e8592f01808c Author: Ron Rindjunsky Date: Mon Nov 26 16:14:36 2007 +0200 iwlwifi: 802.11n new framework structures preperation This patch removes unnecessary or duplicate 802.11n data from structures in the code, and prepares them for new mac80211's 802.11n framework Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 108d3d5f1e3100100528e354236deb1574aed2a4 Author: Ron Rindjunsky Date: Mon Nov 26 16:14:35 2007 +0200 iwlwifi: 802.11n remove unnecessary config dependency This patch removes MAC80211_HT config dependency as it has been eliminated in mac80211, and adds a needed QoS dependency Signed-off-by: Ron Rindjunsky Signed-off-by: John W. Linville commit 8ecfee8774313b255a8f77dcd5538f3cc9c48a03 Author: Zhu Yi Date: Thu Nov 22 10:53:22 2007 +0800 iwlwifi: cache mac80211 conf setting during a hardware scan This patch caches mac80211 configuration setting during a hardware scan for the iwlwifi drivers. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit a6135337163f49dee58f4b0e1af9336bfbe2c589 Author: Miguel Botón Date: Sun Nov 25 15:58:07 2007 +0100 iwlwifi: remove redundant declaration of 'iwl3945_priv' and 'iwl4965_priv' structs This patch removes a redundant declaration of 'iwl3945_priv' and 'iwl4965_priv' structs. Signed-off-by: Miguel Boton Signed-off-by: John W. Linville commit d7b0762116cb51444ad631af8d221a1140799d21 Author: Zhu Yi Date: Thu Nov 29 11:10:16 2007 +0800 iwlwifi: update version number to 1.2.22 Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 509e9558d5aca8ebc22ca36ff1d5966182a93420 Author: Mohamed Abbas Date: Thu Nov 29 11:10:15 2007 +0800 iwlwifi: avoid firmware command sending if rfkill is enabled This patch fixed a ucode timeout issue and worked code with suspend to disk. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit d10058ccfb6fb735dc45dbbf4abf202d37092a96 Author: Mohamed Abbas Date: Thu Nov 29 11:10:14 2007 +0800 iwlwifi: fix ucode assertion for RX queue overrun This patch allows the driver to restock the RX queue early if the RX queue is almost empty. This will help on avoiding any ucode assert for the RX overrun problem. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit cc33406d47ecff5f2086e689e2685b764d42099c Author: Mohamed Abbas Date: Thu Nov 29 11:10:13 2007 +0800 iwlwifi: enhance WPA authenication stability This patch enhanced WPA authenication stability by avoiding scan immediately followed by association. We don't do any scanning right after association in next several seconds. This will allow WPA authentication to take place without any interruption. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit daa1f76df613e1ae8a97edf9a5551823c93b77a6 Author: Ben Cahill Date: Thu Nov 29 11:10:12 2007 +0800 iwlwifi: document 4965 rate scaling Document 4965 rate scaling Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 4790c399bea62ff55b70b469e9c58a74895cba01 Author: Ben Cahill Date: Thu Nov 29 11:10:11 2007 +0800 iwlwifi: add comments to Tx commands Add comments to Tx commands Clean up unused definitions in iwl-3945-commands.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 37356fd0e36481d4a01599e328269e088638efa4 Author: Ben Cahill Date: Thu Nov 29 11:10:10 2007 +0800 iwlwifi: add comments to QOS and ADD_STA commands Add comments to QOS and ADD_STA commands Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 5cb10e425c9080904689daa304f0faeae64bd91a Author: Ben Cahill Date: Thu Nov 29 11:10:09 2007 +0800 iwlwifi: add comments to RXON command and txpower formats Add comments to RXON command and txpower formats Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit de3b9890683778653bedb49e86035d2812d288b3 Author: Ben Cahill Date: Thu Nov 29 11:10:08 2007 +0800 iwlwifi: document command header and "alive" responses Document command header and "alive" responses Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit b9e6f2c60bb267ab072b56ce152406e01bf21f3e Author: Ben Cahill Date: Thu Nov 29 11:10:07 2007 +0800 iwlwifi: document 4965 Tx scheduler Document 4965 Tx scheduler Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit b4dfcff5755b3d1ba53523852675023641bc7350 Author: Ben Cahill Date: Thu Nov 29 11:10:06 2007 +0800 iwlwifi: document shared Tx structures Document shared Tx structures Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 216f588dacf681458dcf96823deb9ef6d56a9ab9 Author: Ben Cahill Date: Thu Nov 29 11:10:05 2007 +0800 iwlwifi: document Tx registers Document Tx registers Clean up unused definitions Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 94c4ea2b827d36b735835089568fea90bf15fc82 Author: Ben Cahill Date: Thu Nov 29 11:10:04 2007 +0800 iwlwifi: document Rx registers Document Rx registers Document Tx circular buffer base registers Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit c8c0ab71565f660ab6e026cd1701e94a3249e327 Author: Ben Cahill Date: Thu Nov 29 11:10:03 2007 +0800 iwlwifi: document keep-warm buffer Document keep-warm buffer Consolidate flow handler address definitions Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 911e902dce0faa721b34e14d10fba3a0b30d204a Author: Ben Cahill Date: Thu Nov 29 11:10:02 2007 +0800 iwlwifi: document txpower calculations Document txpower calculations Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 45a8180e3756758bbe55501a32d41a4b6098a59b Author: Ben Cahill Date: Thu Nov 29 11:10:01 2007 +0800 iwlwifi: document temperature calculation Document temperature calculation Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 89be69c7df54bf99b791a3c6ab6c9e7e1f557d27 Author: Ben Cahill Date: Thu Nov 29 11:10:00 2007 +0800 iwlwifi: move HT_IE_EXT_CHANNEL_* driver definitions to iwl-4965.h Move HT_IE_EXT_CHANNEL_* driver definitions to iwl-4965.h Add comments to guide .h file usage (hw/api/driver definitions) Minor comment cleanup Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 16fbbce122ef411f9e60afe8f2efe47e48888726 Author: Ben Cahill Date: Thu Nov 29 11:09:59 2007 +0800 iwlwifi: move uCode API definitions to iwl-4965-commands.h Move uCode API definitions to iwl-4965-commands.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit cce44ed1aa91fdac8ba68198a5aa7dc2e1bc60f0 Author: Ben Cahill Date: Thu Nov 29 11:09:58 2007 +0800 iwlwifi: clean up unused definitions in iwl-4965-hw.h Clean up unused definitions in iwl-4965-hw.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 57837313667069000400079664dcb5b4436265e5 Author: Ben Cahill Date: Thu Nov 29 11:09:57 2007 +0800 iwlwifi: Clean up unused definitions in iwl-3945-hw.h Clean up unused definitions in iwl-3945-hw.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 7d33bb36f5835f9887f45bf3bda7085576c30fce Author: Cahill, Ben M Date: Thu Nov 29 11:09:55 2007 +0800 iwlwifi: add comments to iwl*-base.c Add comments to iwlXXXX-base.c Signed-off-by: Cahill, Ben M Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit bb1b5934b80ac0bced0c2639c2466c0bc694137c Author: Cahill, Ben M Date: Thu Nov 29 11:09:54 2007 +0800 iwlwifi: add comments, mostly on Tx queues Add comments, mostly on Tx queues Signed-off-by: Cahill, Ben M Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 3c60bc53cf9544e2ab3ec414bdaa810c29627d90 Author: Ben Cahill Date: Thu Nov 29 11:09:53 2007 +0800 iwlwifi: clean up some unused definitions in iwl-4965.h and iwl-3945.h Clean up some unused definitions in iwl-4965.h and iwl-3945.h Move STA_FLG_ definitions to iwl-4965-commands.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 4c2612a460ce851cdb998a6c9d39ac81a485d11f Author: Ben Cahill Date: Thu Nov 29 11:09:52 2007 +0800 iwlwifi: Partially clean-up, add comments to iwl-*-hw.h Partially clean-up, add comments to iwl-XXXX-hw.h Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 3bd7841ea04168bdb591f5664ff8fc7b759673f6 Author: Ben Cahill Date: Thu Nov 29 11:09:51 2007 +0800 iwlwifi: Document Rx calibration Document Rx calibration Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 0595ed3faf18e555c4c3099b439286fac55fd7d9 Author: Ben Cahill Date: Thu Nov 29 11:09:50 2007 +0800 iwlwifi: Document 4965 rate_n_flags bits Document 4965 rate_n_flags bits Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit e8c6b1b7238808f618f0b57cece77ce424f516b8 Author: Ben Cahill Date: Thu Nov 29 11:09:49 2007 +0800 iwlwifi: Add comments to some driver data structures Add comments to some driver data structures Remove unused "sched_retry" member from struct iwl3945_tx_queue Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 895a8bce5405a7ca80efbcb67d7ea145885f42f7 Author: Ben Cahill Date: Thu Nov 29 11:09:48 2007 +0800 iwlwifi: Move is_legacy() macro family from iwl-4965-hw.h to iwl-4965-rs.h Move is_legacy() macro family from iwl-4965-hw.h to iwl-4965-rs.h These macros are for driver's rate scaling implementation, and are not related to hardware or uCode API values (moved from iwl-4965-hw.h). Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit e549a146349e1c082be5834ebcd899d429387437 Author: Ben Cahill Date: Thu Nov 29 11:09:47 2007 +0800 iwlwifi: clean up and clarify some comments after 3945/4965 split Clean up and clarify some comments after 3945/4965 split. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit c87d1523d04eb4b6f28306e576b1003f728d39c5 Author: Ben Cahill Date: Thu Nov 29 11:09:46 2007 +0800 iwl-4965-hw.h: clean up unused eeprom structures and definitions Clean up unused eeprom structures and definitions in iwl-4965-hw.h. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 4a4f9432fa4ddcd56b8c9a346148d47238e39f9d Author: Ben Cahill Date: Thu Nov 29 11:09:45 2007 +0800 iwlwifi: add comments to EEPROM stuff Add comments to EEPROM stuff. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 04b55b58942f2d628c288e7e16fa5865bf08fb5c Author: Ben Cahill Date: Thu Nov 29 11:09:44 2007 +0800 iwl4965: add comments to rate scaling code Add comments to rate scaling code. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit ddbefca51ef979713579c514b1b720222498348b Author: Ben Cahill Date: Thu Nov 29 11:09:43 2007 +0800 iwl3945: re-align 3945 event log data Re-align 3945 event log data. Signed-off-by: Ben Cahill Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 08f1cf61001d1db328c3f2397c02955da9ce90c9 Author: Reinette Chatre Date: Thu Nov 29 11:09:42 2007 +0800 iwlwifi: continue namespace changes - fix CONFIG variables - Remove HT code from iwl-3945.h - it is not needed here as 3945 does not support HT. The code ended up here during the header file split. - Modify a few places where the CONFIG variables were named incorrectly: all changes are to comments only. Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville commit 32bf7f04ab5111cb9be385da69d813d4503f8170 Author: Tomas Winkler Date: Thu Nov 29 11:09:41 2007 +0800 iwlwifi: Support for uCode without init and bsm section This patch enables loading fw w/o init and bsm section. It also provides general cleanup of the rutine. Signed-off-by: Tomas Winkler Signed-off-by: Gregory Greenman Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 15bf1fac2804bf191e9306c19b1da97c7829c20a Author: Ivo van Doorn Date: Tue Nov 27 21:52:13 2007 +0100 rt2x00: Release rt2x00 2.0.13 Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit a3688cbecf3c428930080756637361f3b6041a98 Author: Ivo van Doorn Date: Tue Nov 27 21:51:57 2007 +0100 rt2x00: Cleanup rfkill The label exit_free_polldev is no longer used and can be removed. input_free_polled_device() also calls input_free_device(), so don't call it seperatly. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 6895bfa03dec7eece70b75e225ae31efe4734b0b Author: Larry Finger Date: Tue Nov 27 21:51:39 2007 +0100 rt2x00: Remove redundant code in rfkill setup In rt2x00rfkill.c, routine input_allocate_device() is called even though input_allocate_polled_device(), which was just called, includes a call to that routine. This patch, which has not been tested, removes the redundant code. Signed-off-by: Larry Finger Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit a448082a2c38d5472140b891cea6a40442e463a7 Author: Mattias Nissler Date: Tue Nov 27 21:50:26 2007 +0100 rt2x00: Only update rssi average approximation on receiving beacon frames. Restrict rssi average updating to beacon frames of the bssid the interface is associated with. Without this restriction, strong signals belonging to other BSS, e.g. beacon frames coming from a nearby AP, would cause incorrectly high rssi approximation values. This would then cause the link tuner to reduce sensitivity, resulting in transmissions from the BSS associated to to be missed. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit ca1d1b0050ddbf0453aa10c261a14ca84c35cd7d Author: Ivo van Doorn Date: Tue Nov 27 21:49:50 2007 +0100 rt2x00: Use IEEE80211_IF_TYPE_INVALID directly No need to use a seperate define INVALID_INTERFACE while we can use IEEE80211_IF_TYPE_INVALID directly. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit f33a4b43abcb188e6cd445768572935845a801d6 Author: Ivo van Doorn Date: Tue Nov 27 21:49:29 2007 +0100 rt2x00: Add TX/RX frame dumping facility This adds TX/RX frame dumping capabilities through debugfs. The intention is that with this approach debugging of rt2x00 is simplified since _all_ frames going in and out of the device are send to debugfs as well along with additional information like the hardware descriptor. Based on the patch by Mattias Nissler. Mattias also has some tools that will make the dumped frames available to wireshark: http://www-user.rhrk.uni-kl.de/~nissler/rt2x00/ Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit a94eb9f72e850e8a6a18979b120cc3db47529443 Author: Ivo van Doorn Date: Tue Nov 27 21:49:05 2007 +0100 rt2x00: Add skb descriptor Use the skb->cb field to add a frame description that can be used to transfer information passed each rt2x00 layer. This reduces the required arguments for rt2x00lib_write_tx_desc(). Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 5781fac083acf48af44aed34dc7f152a239d8f00 Author: Ivo van Doorn Date: Tue Nov 27 21:48:37 2007 +0100 rt2x00: Add chipset version to chipset debugfs entry The chipset debugfs entry already indicates it is about the chipset, it only makes sense to also display the chipset version in there. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit a0bc893630d2fa6dff07a3462eee3270fcc2d27b Author: Ivo van Doorn Date: Tue Nov 27 21:48:16 2007 +0100 rt2x00: Move register value/offset files into new folder Cleanup debugfs interface by moving the csr/bbp/rf/eeprom value/offset entries into the "register" folder. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit e7a62550ca9fdff895fa66d1bac5863ccab84713 Author: Ivo van Doorn Date: Tue Nov 27 21:47:56 2007 +0100 rt2x00: Extend PLCP descriptor definition for rt2400pci Extend word field definitions for the PLCP words in the TX descriptor to contain the BBP fields as well. This will remove rt2400pci_write_tx_desc() from the checkstack script. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 11322e98d3127a743f8860a2db00c311d9648de4 Author: Ivo van Doorn Date: Tue Nov 27 21:47:34 2007 +0100 rt2x00: Replace DRV_NAME with KBUILD_MODNAME DRV_NAME was always set to the KBUILD_MODNAME value, lets clean everything up by removing DRV_NAME and just use KBUILD_MODNAME directly. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 5de4d46320af930d17c7701e0b321a076061baa1 Author: Stefano Brivio Date: Sat Nov 24 23:35:25 2007 +0100 b43legacy: reinit on too many PHY TX errors Restart the hardware on too many PHY TX errors. A thousand PHY TX errors per 15 seconds means we won't be able to recover for sure. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville commit 1818e644e4f397942da0e12d6e895f1f4b5684fe Author: Johannes Berg Date: Sat Nov 24 21:11:09 2007 +0100 b43legacy: include full 64-bit timestamp in monitor mode When monitor mode is enabled, this will make b43legacy read out the full 64-bit MAC time from the chip for each received packet. This patch has been ported from b43. Signed-off-by: Stefano Brivio Cc: Johannes Berg Signed-off-by: John W. Linville commit 26892307812a215f700c2cd5a1c40bde3f01ce00 Author: Frank Lichtenheld Date: Sat Nov 24 21:11:08 2007 +0100 b43legacy: properly fix a bogus gcc warning Use initialized_var() to properly fix a bogus gcc warning. Signed-off-by: Stefano Brivio Cc: Frank Lichtenheld Signed-off-by: John W. Linville commit 8af8b58716dbcc3e41e30b36b490dbc08e133461 Author: Larry Finger Date: Mon Nov 26 10:29:47 2007 -0600 b43: Changes to enable BCM4311 rev 02 with wireless core revision 13 The BCM94311MCG rev 02 chip has an 802.11 core with revision 13 and has not been supported until now. The changes include the following: (1) Add the 802.11 rev 13 device to the ssb_device_id table to load b43. (2) Add PHY revision 9 to the supported list. (3) Change the 2-bit routing code for address extensions to 0b10 rather than the 0b01 used for the 32-bit case. (4) Remove some magic numbers in the DMA setup. The DMA implementation for this chip supports full 64-bit addressing with one exception. Whenever the Descriptor Ring Buffer is in high memory, a fatal DMA error occurs. This problem was not present in 2.6.24-rc2 due to code to "Bias the placement of kernel pages at lower PFNs". When commit 44048d70 reverted that code, the DMA error appeared. As a "fix", use the GFP_DMA flag when allocating the buffer for 64-bit DMA. At present, this problem is thought to arise from a hardware error. This patch has been tested on my system and by Cédric Caumont . Signed-off-by: Larry Finger Acked-by: Michael Buesch Signed-off-by: John W. Linville commit fcb7718f545e627949141b322ec039739e4a7bab Author: Stefano Brivio Date: Sun Nov 25 11:10:33 2007 +0100 b43: reinit on too many PHY TX errors Restart the hardware on too many PHY TX errors. A thousand PHY TX errors per 15 seconds means we won't be able to recover for sure. Signed-off-by: Stefano Brivio Signed-off-by: Michael Buesch Signed-off-by: John W. Linville commit 75aea7bfa89e2a8b1ab44935c0d754fdd3fde723 Author: Johannes Berg Date: Sat Nov 24 15:06:33 2007 +0100 b43: include FCS in frames handed to mac80211 Sometimes it can be useful to see the FCS, especially when bad-FCS frames are shown. Pass the FCS to mac80211 and let it worry about snipping it off when required. Signed-off-by: Johannes Berg Signed-off-by: Michael Buesch Signed-off-by: John W. Linville commit 1dded8c24c8b40bf4c57a11f86bfa689577b9a8b Author: Johannes Berg Date: Fri Nov 23 14:50:51 2007 +0100 b43: include full 64-bit timestamp in monitor mode When monitor mode is enabled, this will make b43 read out the full 64-bit MAC time from the chip for each received packet. Signed-off-by: Johannes Berg Signed-off-by: Michael Buesch Signed-off-by: John W. Linville commit 028029abe73f3d91f40175498b3d794507d800a3 Author: Holger Schurig Date: Wed Nov 28 09:15:11 2007 +0100 libertas: less eventcause shifts * only shift eventcause once * convert mac events to decimal, as this is what the firmware manual uses in section 6.1, too Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit 4dcb992a060e5e20a2c0085441a6d0cbfe7b4093 Author: Holger Schurig Date: Wed Nov 28 17:30:21 2007 +0100 libertas: remove user-specified channel list Remove the ability to specify channels to scan via debugfs Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit b5513ef7746b0d74eb932ba03b2ef52789d832b0 Author: Holger Schurig Date: Wed Nov 28 17:29:36 2007 +0100 libertas: remove numprobes Remove the ability to specify number of probes via debugfs Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit 24ef9c28f1e1d6acac8f6ea542e314d8a4b3e548 Author: Holger Schurig Date: Wed Nov 28 14:08:12 2007 +0100 libertas: tweak tx path debugging Make two functions in the TX packet path emit their debug messages with LBS_DEB_TX, not LBS_DEB_MAIN. Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit 3e23ee6efee049e33041f600418b0dd0491a7218 Author: Holger Schurig Date: Wed Nov 28 14:05:02 2007 +0100 libertas: tweak association debug output Change debug output codes from LBS_DEB_JOIN to LBS_DEB_ASSOC Signed-off-by: Holger Schurig Signed-off-by: John W. Linville commit 8329a4232f1b4c06fac561ae3003467d90bdfe3d Author: Holger Schurig Date: Mon Nov 26 10:07:14 2007 +0100 libertas: rework event subscription This patch moves re-works the implementation of event subscription via debugfs. For this: * it tells cmd.c and cmdresp.c about CMD_802_11_SUBSCRIBE_EVENT * removes lots of low-level cmd stuff from debugfs.c * create unified functions to read/write snr, rssi, bcnmiss and failcount * introduces #define's for subscription event bitmask values * add a function to search for a specific element in an IE (a.k.a. TLV) * add a function to find out the size of the TLV. This is needed because lbs_prepare_and_send_command() has an argument for a data buffer, but not for it's lengths and TLVs can be, by definition, vary in size. * fix a bug where it was not possible to disable an event Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit cf1ed041f2f2376f9791b11bf7c0d10b46bf6f30 Author: Holger Schurig Date: Fri Nov 23 15:43:44 2007 +0100 libertas: remove arbitrary typedefs New typedefs are usually frowned upon. This patch changes libertas_adapter -> struct libertas_adapter libertas_priv -> struct libertas_priv While passing, make everything checkpatch.pl-clean that gets touches. Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit ed64cfe206e42fe31935af008231bf20ec719b28 Author: Brajesh Dave Date: Tue Nov 20 17:44:28 2007 -0500 libertas: configurable beacon interval Requires firmware version 5.110.19.p0 or newer, available here: http://dev.laptop.org/pub/firmware/libertas/ Signed-off-by: Ashish Shukla Signed-off-by: Javier Cardona Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit 3bb07c72f61e54373e6596cb0c3870468e60e50c Author: Brajesh Dave Date: Tue Nov 20 17:44:14 2007 -0500 libertas: separate mesh connectivity from that of the main interface The transmit and receive traffic as soon as the mesh interface is brought up. Test case 1: Bring up only the mesh interface and ping. No need for any iwconfig commands on the main interface. $ ifconfig msh0 192.168.5.3 $ iwconfig msh0 channel X $ ping 192.168.5.2 If ping succeeds, PASS Test case 2: Associate with the main interface, and turn off AP. Mesh interface should not lose connectivity. $ iwconfig eth0 mode managed essid "my_ssid" $ ifconfig msh0 192.168.5.3 $ ping 192.168.5.2 If ping continues uninterrupted, PASS This feature requires firmware version 5.110.19.p0 or newer, available here: http://dev.laptop.org/pub/firmware/libertas/ Signed-off-by: Ashish Shukla Signed-off-by: Javier Cardona Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit 39fa2ca080ea1d21a43bad4840cf07550d76d4c9 Author: Andres Salomon Date: Tue Nov 20 17:44:04 2007 -0500 libertas: nuke useless variable usbdriver_name and useless comments I think it was pretty obvious what fields in if_usb_driver are... Signed-off-by: Andres Salomon Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit 44719745ffd5b8eb679539bcd4bb6bbbc64eb6f6 Author: Andres Salomon Date: Tue Nov 20 17:43:55 2007 -0500 libertas: reset devices upon disconnect rather than module unloading 1) Do not reset libertas devices upon module unload. We're unloading the module, we're not killing off devices. 2) Instead, reset libertas devices inside if_usb_disconnect, as we're killing off interfaces and so on. 3) Resetting via disconnect callback means we no longer need to keep track of probed libertas devices; kill off that list (and its wonderful lack of locking..), as well. Drop a useless comment as well. Signed-off-by: Andres Salomon Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit 3a808faafc2cd7dd58395931154ceef8abb0684f Author: Andres Salomon Date: Tue Nov 20 17:43:45 2007 -0500 libertas: mark module_init/exit functions as __init/__exit Signed-off-by: Andres Salomon Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit bef6d785c960c8cc7b9ae249f7547ae5dd6e29ba Author: Andres Salomon Date: Tue Nov 20 17:43:32 2007 -0500 libertas: drop useless default_fw_name variable Signed-off-by: Andres Salomon Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit a52c52924a82c3ac3561b6854e8b460af340d727 Author: Daniel Drake Date: Mon Nov 19 16:20:12 2007 +0000 zd1211rw: add copyright notices Requested by Michael Wu. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville commit 540b30dde69164f57c7ee64bdd68794e59c0f2b5 Author: Daniel Drake Date: Mon Nov 19 15:29:24 2007 +0000 zd1211rw: Add ID for Trendnet TEW-429UB A Tested by chloubs on IRC zd1211 chip 157e:300a v4810 high 00-11-e0 AL7230B_RF pa0 g---- Signed-off-by: Daniel Drake Signed-off-by: John W. Linville commit 38ee9a98a4fa1417cf882bc23c427e0bceefb458 Author: Daniel Drake Date: Mon Nov 19 15:00:29 2007 +0000 zd1211rw: port to mac80211 This seems to be working smoothly now. Let's not hold back the mac80211 transition any further. This patch ports the existing driver from softmac to mac80211. Many thanks to everyone who helped out with the porting efforts. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville commit 1b2a1033c83af797fc58c38be1bc7a793e0dd86b Author: Ulrich Kunitz Date: Sat Dec 1 11:26:05 2007 +0100 zd1211rw: Fix alignment problems Shaddy Baddah found an alignment problem with zd1211rw driver at 2007-11-19. This patch fixes it, it is based on the patch proposed by Herbert Xu. The alignment 4 has been the agreed value on the linux-wireless mailing list. Notify that the problem does only affect the old zd1211rw softmac driver and not the zd1211rw-mac80211 driver. Daniel Drake has already provided a patch for the replacement of the softmac driver, which this patch will break. Signed-off-by: Ulrich Kunitz Signed-off-by: John W. Linville commit a8f5324d8c5fa5c28c33fd25c66bc958a43532f1 Author: Holger Schurig Date: Mon Oct 15 12:55:56 2007 +0200 libertas: clean up association debug messages This makes the debug output of all association stuff clearer by: * adding some lbs_deb_enter()/lbs_deb_leave() calls * printing the return level in one place * lower-casing some string Signed-off-by: Holger Schurig Signed-off-by: John W. Linville commit 7b1e850c840bde3d06792b74f6219611187f69f9 Author: Holger Schurig Date: Thu Nov 15 18:05:47 2007 -0500 libertas: move to uniform lbs_/LBS_ namespace This patch unifies the namespace of variables, functions defines and structures. It does: - rename libertas_XXX to lbs_XXX - rename LIBERTAS_XXX to lbs_XXX - rename wlan_XXX to lbs_XXX - rename WLAN_XXX to LBS_XXX (but only those that were defined in libertas-local *.h files, e.g. not defines from net/ieee80211.h) While passing, I fixed some checkpatch.pl errors too. Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit 9d30cda9248e78e7d5ac2bcc4e5a625f1a8008dd Author: John W. Linville Date: Thu Nov 15 16:27:36 2007 -0500 iwlwifi: remove redundant initialization of final_mode Problem identified by Miguel Botón , alternate solution suggested by Zhu Yi , patch by me. :-) Cc: Miguel Botón Cc: Zhu Yi Signed-off-by: John W. Linville commit 0959eb27ca638bfe71932b29264f589b1f6715fe Author: Larry Finger Date: Fri Nov 9 16:58:20 2007 -0600 ssb: Remove the old, now unused, data structures The old, now unused, data structures and SPROM extraction routines are removed. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 1c12f4e2442552794b6322a27965411a9ae7042e Author: Larry Finger Date: Fri Nov 9 16:57:34 2007 -0600 b43legacy: Convert to use of the new SPROM structure The b43legacy driver is modified to use the new SPROM structure. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 6b7e0f98f4f1c9328ac22901c17edc40076dfb2e Author: Larry Finger Date: Fri Nov 9 16:57:18 2007 -0600 b43: Convert to use of the new SPROM structure The b43 driver is modified to use the new SPROM structure. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 46080a9c230090a704958b454d187c9abcac2be3 Author: Larry Finger Date: Fri Nov 9 16:56:10 2007 -0600 b44: Convert to use of the new SPROM structure The b44 driver is changed to use the new SPROM data structure. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 0edbe252eb0ccb5a9d11abbde1954809dec41748 Author: Larry Finger Date: Fri Nov 9 16:56:25 2007 -0600 ssb: Convert to use of the new SPROM structure In disagreement with the SPROM specs, revision 3 devices appear to have moved the MAC address. Change ssb to handle the revision 4 SPROM, which is a different size. This change in size is handled by adding a new variable to the ssb_sprom struct and using it whenever possible. For those routines that do not have access to this structure, a 'u16 size' argument is added. The new PCI_ID for the BCM4328 is also added. Testing of the Revision 4 SPROM, which is used on the BCM4328, was done by Michael Gerdau . Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit e1de6a0204d30dd6dbe3b3e383c098d9e18ffb29 Author: Larry Finger Date: Fri Nov 9 16:54:45 2007 -0600 ssb: Add new SPROM structure while keeping the old The SPROM's for various devices utilizing the Sonics Silicon Backplane come with various revisions. The Revision 2 SPROM inherited the data layout of 1, and Revision 3 inherited the layout of 2. The first instance of Revision 4 has now been found in a BCM4328 wireless LAN card. This device does not inherit any layout from previous versions. Although it was possible to create a data structure that kept all the old layouts, we decided to start fresh, keep only those SPROM variables that are used by the drivers that utilize ssb, and to do the conversion in such a manner that neither compilation or execution will be affected if a bisection lands in the middle of these changes, while keeping the patches as small as possible. In this patch, the sprom structures are changed while maintaining the old ones. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit bdfb978d2e1136187695a1ae32098b764f1ab7f1 Author: Mattias Nissler Date: Mon Nov 12 15:03:12 2007 +0100 rt2x00: Allow rt61 to catch up after a missing tx report Sometimes it happens in the tx path that an entry given to the hardware isn't reported in the txdone handler. This ultimately led to the dreaded "non-free entry in the non-full queue" message and the stopping of the tx queue. Work around this issue by allowing the driver to also clear out previos entries in the txdone handler. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit bb0fb2af3578fbe8b845bb13b476cdff4cd656a7 Author: Ivo van Doorn Date: Mon Nov 12 15:02:40 2007 +0100 rt2x00: Move duplicate code into rt2x00pci_txdone() rt2400pci, rt2500pci and rt61 require different txdone handling, but the code that pushes the frame upstream and cleans up the entry is identical to all of them. This will create the function rt2x00pci_txdone() to remove the duplicate code. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 4f3a9d5f376208c71dfa5856fd855cb0faae1b64 Author: Zhu Yi Date: Mon Nov 12 11:37:43 2007 +0800 iwl4965: fix rxon flags set to wrong value for A mode in .erp_ie_changed The patch fixes a bug that enables RXON_FLG_TGG_PROTECT_MSK erroneously for A mode in the erp_ie_changed mac80211 callback. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 572f5be631840eff985fe482c8e6a45ace636d3e Author: Frank Lichtenheld Date: Mon Nov 12 11:12:52 2007 +0100 b43: silence a bogus gcc warning use uninitialized_var() to avoid the following bogus warning: CC [M] drivers/net/wireless/b43/debugfs.o drivers/net/wireless/b43/debugfs.c: In function ‘b43_debugfs_read’: drivers/net/wireless/b43/debugfs.c:355: warning: ‘ret’ may be used uninitialized in this function Signed-off-by: Michael Buesch Signed-off-by: Frank Lichtenheld Signed-off-by: John W. Linville commit 15bc6673b452c61a8286d3a1502f820fb1b10a60 Author: Stefano Brivio Date: Thu Nov 8 00:28:00 2007 +0100 b43legacy: fix kconfig dependecies for rfkill and leds Fix dependencies for built-in b43legacy. The patch to b43 by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville commit aa781358d9606fbde082d09d544b32506102f697 Author: Reinette Chatre Date: Tue Nov 6 22:06:28 2007 -0800 MAINTAINERS: Add Reinette Chatre to iwlwifi & ipw2100/ipw2200 Also fix Zhu Yi's name. Signed-off-by: Reinette Chatre CC: Zhu Yi Signed-off-by: John W. Linville commit feb22185a1db1fbdbbc66c0fa32315b35cb8eb1e Author: Zhu Yi Date: Tue Nov 6 22:06:27 2007 -0800 remove unused iwl4965_init_hw_rates function The patch removes the unused function to fix a recursive bug caused by namespace change. Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville commit 68fa7e1b5a08667bfbf6072293b0f6be3cce3347 Author: Christoph Hellwig Date: Tue Nov 6 22:06:26 2007 -0800 iwlwifi: cleanup namespace Prefix all symbols with iwl3945_ or iwl4965_ and thus allow building the driver into the kernel. Also remove all the useless default statements in Kconfig while we're at it. Signed-off-by: Christoph Hellwig Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville commit f1b5bbbb23e03b8caf482cae63022eca31170747 Author: Mohamed Abbas Date: Tue Nov 6 22:06:25 2007 -0800 iwl4965: fix cannot find a suitable rate issue This patch fixes the iwl4965 problem for "Can not find a suitable rate issues." by making rs_switch_to_mimo and rs_switch_to_siso functions return -1 when CONFIG_IWL4965_HT is not selected. They used to return 0, which means we can switch to HT rate causing the rate scale problem and the error message. The patch also fix another bug reported by Ben Cahill that it uses wrong value for max_success_limit. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville commit 2179ea702211ec18162559248b92abf3c03442ef Author: Zhu Yi Date: Tue Nov 6 22:06:24 2007 -0800 iwlwifi: replace 0x8086 with PCI_VENDOR_ID_INTEL Replace 0x8086 with PCI_VENDOR_ID_INTEL for PCI_DEVICE declaration. Signed-off-by: Zhu Yi Signed-off-by: Reinette Chatre Signed-off-by: John W. Linville commit e9a52affa8eb38f5ae49de45c3190cd204925454 Author: Stefano Brivio Date: Tue Nov 6 22:49:20 2007 +0100 b43/b43legacy: fix my copyright notices Fix my copyright notices in b43 and b43legacy. Signed-off-by: Stefano Brivio Cc: Michael Buesch Signed-off-by: John W. Linville commit 2ab94bef6f52d096a51c84187977a4f608323193 Author: Stefano Brivio Date: Tue Nov 6 22:49:05 2007 +0100 b43: rewrite A PHY initialization Rewrite and sync A PHY initialization with specs, thus allowing for further work to be done on 802.11a support. Note that A PHY initialization involves G PHYs as well. Signed-off-by: Stefano Brivio Acked-by: Michael Buesch Signed-off-by: John W. Linville commit 3d8f268f4a134fbb5d67e59c2138302fa39de729 Author: Stefano Brivio Date: Tue Nov 6 22:48:45 2007 +0100 b43legacy: rewrite and fix rfkill initialization The rfkill subsystem doesn't like code like that rfkill_allocate(); rfkill_register(); rfkill_unregister(); rfkill_register(); /* <- This will crash */ This sequence happens with modprobe b43 ifconfig wlanX up ifconfig wlanX down ifconfig wlanX up Fix this by always re-allocating the rfkill stuff before register. The patch to b43 by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville commit 8c891c7d53239190cf7eaa75502a04035a84e4e2 Author: Stefano Brivio Date: Tue Nov 6 22:48:25 2007 +0100 b43legacy: use a consistent naming scheme for the ops Use a consistent naming scheme for the ops. The patch to b43 by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville commit 6f8fe3078fb9fec8d3145489acc44a26b6b197e3 Author: Stefano Brivio Date: Tue Nov 6 22:48:12 2007 +0100 b43legacy: use the retry limits provided by mac80211 Use the retry limits provided by mac80211. The patch to b43 by Michael Buesch has been ported to b43legacy. Signed-off-by: Stefano Brivio Signed-off-by: John W. Linville commit 93a437556475145ec1147792873e15666dece6ee Author: Thomas Bogendoerfer Date: Sat Nov 24 13:29:19 2007 +0100 SGISEEQ: use cached memory access to make driver work on IP28 SGI IP28 machines would need special treatment (enable adding addtional wait states) when accessing memory uncached. To avoid this pain I changed the driver to use only cached access to memory. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Jeff Garzik commit ad44f99f7fbb282a2848c456f118270babe2aa36 Author: Olof Johansson Date: Wed Nov 28 20:58:25 2007 -0600 pasemi_mac: Don't enable RX/TX without a link (if possible) pasemi_mac: Don't enable RX/TX without a link (if possible) Don't enable RX/TX of packets until we have a link, since there's a chance we'll just get RX frame errors, etc. The case where we don't have a PHY we can't do much about: Just enable it and deal with errors as they come in. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 7e17163db9cf4d1cfb4af5d293c865489fbf9c62 Author: Olof Johansson Date: Wed Nov 28 20:58:06 2007 -0600 pasemi_mac: Print warning when not attaching to a PHY pasemi_mac: Print warning when not attaching to a PHY Print a warning on the console when not connecting to a phy for an interface. It turns out to be a pretty common problem when someone gets the MDIO info wrong in their device tree, resulting in the macs running at a fixed 1Gbit FD. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit bdb15107c215b6230c764721b756c52bed56549a Author: Olof Johansson Date: Wed Nov 28 20:57:56 2007 -0600 pasemi_mac: Remove SKB copy/recycle logic pasemi_mac: Remove SKB copy/recycle logic It doesn't really buy us much, since copying is about as expensive as the allocation in the first place. Just remove it for now. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit ae0d9581192844358121915f84a8d7160fae2c1e Author: Olof Johansson Date: Wed Nov 28 20:57:45 2007 -0600 pasemi_mac: SKB unmap optimization pasemi_mac: SKB unmap optimization Avoid touching skb_shinfo() in the unmap path, since it turns out to normally cause cache misses and delays. instead, save number of fragments in the TX_RING_INFO structures since that's all that's needed anyway. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit dd75b63fc0abf502175c8a37009820fae3da38e0 Author: Olof Johansson Date: Wed Nov 28 20:57:27 2007 -0600 pasemi_mac: Software-based LRO support pasemi_mac: Software-based LRO support Implement LRO for pasemi_mac. Pretty straightforward. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 63e5039bad4e28a050f5285f1a812fe84675d868 Author: Olof Johansson Date: Wed Nov 28 20:57:09 2007 -0600 pasemi_mac: Improve RX interrupt mitigation pasemi_mac: Improve RX interrupt mitigation Currently the receive side interrupts will go off on the reception of a packet, NAPI will poll the ring and keep polling as long as there's a decent amount of packets to receive. This is less than optimal, especially for LRO where it's better if we have a more substantial amount of packets to process at once, to get the real LRO benefits. So, set the count threshold to a higher value and use the timeout feature that will give us an interrupt even if not enough packets have come in to set off the count threshold. FIXME: It'd be real nice to have ethtool support for users to tune this at runtime. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 96b84353afaa4ffccfd55739c1e493825345eacc Author: Olof Johansson Date: Wed Nov 28 20:56:54 2007 -0600 pasemi_mac: Fix TX cleaning pasemi_mac: Fix TX cleaning This is a bit awkward. We don't have a timer-delayed interrupt on TX complete, but we have a count threshold. So set that reasonably high (32 packets), and schedule the NAPI poll when it goes off. Also bump a regular timer that will take care of rotting packets for the last 1..31 ones in case we don't trigger a TX interrupt (and there's no RX activity that would otherwise trigger the poll). The longer-term fix is to separate TX from RX NAPI and do two separate poll loops. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit a9d71f11f20e3baf9c89e31f7669723b5d2a6979 Author: Olof Johansson Date: Wed Nov 28 20:56:41 2007 -0600 pasemi_mac: performance tweaks pasemi_mac: performance tweaks * Seems like we do better with a smaller RX ring, probably because chances of still having the SKB cached are better * Const-ify variables to get better code generation and fewer reloads * Move prefetching around a little, and try to prefetch the whole SKB * Set NETIF_F_HIGHDMA * Misc other minor tweaks Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 66d608e1c184a5ffb6a6956d660ffaf59667dbcd Author: Olof Johansson Date: Wed Nov 28 20:56:32 2007 -0600 pasemi_mac: Convert to new dma library pasemi_mac: Convert to new dma library Convert the pasemi_mac driver to the new platform global DMA manaagement library. This also does a couple of other minor cleanups w.r.t. channel management. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit dbe2e741fa3eb7bd5621111199173a1bf74a19db Author: Olof Johansson Date: Wed Nov 28 20:56:20 2007 -0600 pasemi: DMA engine management library pasemi: DMA engine management library Introduce a DMA management library to manage the various DMA resources on the PA Semi SoCs. Since several drivers need to allocate these shared resources, provide some abstractions as well as allocation/free functions for channels, etc. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit e4150f5bc0eb342404f3a6c56b5e6273e69f0e24 Author: Olof Johansson Date: Wed Nov 28 20:56:04 2007 -0600 pasemi_mac: Move register definitions to include/asm-powerpc pasemi_mac: Move register definitions to include/asm-powerpc Move the common register formats and descriptor layouts from drivers/net/pasemi_mac.h to include/asm-poewrpc/pasemi_dma.h Previously only the ethernet driver was using them, but other drivers are coming up that will also use them, so it makes sense to share the constants. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 10ac2ab031a900b414d53527086fe88aed5bff46 Author: Olof Johansson Date: Wed Nov 28 20:54:28 2007 -0600 pasemi_mac: RX/TX ring management cleanup pasemi_mac: RX/TX ring management cleanup Prepare a bit for supporting multiple TX queues by cleaning up some of the ring management and shuffle things around a bit. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik commit 5ae197ab4d76b7bd40d035ce6d1c4c139d9999a6 Author: Stephen Hemminger Date: Wed Nov 28 14:50:16 2007 -0800 sky2: rx allocation threshold change When using larger MTU's sky2 driver changes from allocating one data area, to using multiple pages. The threshold for this was based on a heuristic where the cost of a single allocation is bigger than one page. Since the allocator has changed, this heuristic is now incorrect; instead just make the threshold be when the total size of the allocation is greater than one page. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik commit 5d2c382e1d8164cb1e79ad9045544fe054f63d11 Author: Stephen Hemminger Date: Wed Nov 28 14:27:03 2007 -0800 sky2: align IP header on Rx if possible The sky2 driver was not aligning the IP header on receive buffers. This workaround is only needed on hardware with broken FIFO, newer chips without FIFO can just DMA to unaligned address. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik commit 8dd657d2d82657c1d70219a704ccfe4fecfc55be Author: Francois Romieu Date: Wed Nov 28 23:02:33 2007 +0100 r6040: cleanups - whitespaces vs tabs - use 80 cols - use if_mii - use netdev_priv - remove useless cast to void * - PCI device id does not need to be globally available Signed-off-by: Francois Romieu commit f00c12227fe587b6c1bbb6b459394db29dc5fac0 Author: Francois Romieu Date: Wed Nov 28 22:55:36 2007 +0100 r6040: erroneous dev->priv Signed-off-by: Francois Romieu commit c7eaa9bde00c778b53f778d49617353d3b9b0c21 Author: Francois Romieu Date: Wed Nov 28 22:31:00 2007 +0100 r6040: remove virt_to_bus Signed-off-by: Francois Romieu commit cc27eeb9474a87b2073488f37d9e90e6a3557664 Author: Francois Romieu Date: Wed Nov 28 21:36:22 2007 +0100 r6040: compile error drivers/net/r6040.c: In function 'rx_buf_alloc': drivers/net/r6040.c:262: warning: passing argument 2 of 'pci_map_single' makes pointer from integer without a cast Signed-off-by: Francois Romieu commit 02e063b58b7c7084bae3d599c54dcf26c8efa9b7 Author: Komuro Date: Sun Nov 11 11:04:36 2007 +0900 axnet_cs: use spin_lock_irqsave instead of spin_lock + disable_irq Signed-off-by: Komuro Signed-off-by: Jeff Garzik commit b51d623b357a3e9ae836dfc1e93f2dfdcaf3d5d7 Author: Jeff Garzik Date: Fri Nov 23 21:59:45 2007 -0500 drivers/net/cxgb3: trim trailing whitespace Signed-off-by: Jeff Garzik commit 6c2ea4e02c272f97acb8844c754741a2249f4367 Author: Divy Le Ray Date: Fri Nov 16 11:22:21 2007 -0800 cxgb3 - Fix I/O synchronization Synchronize memory access before ringing the Tx door bell. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit f1c6edd337b25817eb8fe04b52b77137b95b7454 Author: Divy Le Ray Date: Fri Nov 16 11:22:16 2007 -0800 cxgb3 - HW set up updates Disable PEX errors. The HW generates false positives. Update RSS hash function to a symmetric algorithm. Update T3C HW support Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 0b752184dda5b48e348522f682bf2a4a8ee93d30 Author: Divy Le Ray Date: Fri Nov 16 11:22:10 2007 -0800 cxgb3 - sysfs methods clean up Remove unused argument in sysfs methods Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 20bd8d18552f610903bb550ebce02e036764e23f Author: Divy Le Ray Date: Fri Nov 16 11:22:05 2007 -0800 cxgb3 - fix interaction with pktgen Do not use skb->cb to stash unmap info, save the info to the descriptor state. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 58ceab73812e16deaf1196b809df358b6bec3dac Author: Divy Le Ray Date: Fri Nov 16 11:22:00 2007 -0800 cxgb3 - FW upgrade Bump up FW version to 5.0. Do not downgrade FW within the same major version range. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 9165db0cf2ae11fb35467edcaf33114dc447b8b1 Author: Divy Le Ray Date: Fri Nov 16 11:21:55 2007 -0800 cxgb3 - Add EEH support Add PCI recovery support Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 020b5605eaa9b555d2d26b727044159878a23047 Author: Divy Le Ray Date: Fri Nov 16 11:21:50 2007 -0800 cxgb3 - Fix resources release. Remove sysfs entries before unregistering the net devices. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit ef92bb56da49c99b965d7aee46915492fbf96acd Author: Divy Le Ray Date: Fri Nov 16 14:26:44 2007 -0800 cxgb3 - Use wild card for PCI subdevice ID match Subdevice ID is not necessarily set to 1. Use wild card for PCI device matching Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit 012a1e0c54b21cc260f2b6cd80505f43ed00cf4e Author: Divy Le Ray Date: Fri Nov 16 11:21:39 2007 -0800 cxgb3 - fix MSI-X failure path Return error code when msi-x settings fail. Signed-off-by: Divy Le Ray Signed-off-by: Jeff Garzik commit b94441752719d8c092a777de68fd7ab1334211aa Author: Jeff Garzik Date: Fri Nov 23 21:50:34 2007 -0500 [netdrvr] checkpatch cleanups Signed-off-by: Jeff Garzik commit b00aed29925baf015efae4b4a4462623723e5fba Author: Jeff Garzik Date: Fri Nov 23 21:50:20 2007 -0500 wireless: checkpatch cleanups Signed-off-by: Jeff Garzik commit d2dc347cf659070589417da10fc2e963db3b0577 Author: Jeff Garzik Date: Fri Nov 23 21:49:27 2007 -0500 drivers/net/r6040: fix obvious problems (but more remain) - checkpatch fixes - fix bogus and uninitialized return codes in r6040_start_xmit() - netdev_get_settings() fix obvious locking bug flagged by compiler warning - set DMA consistent mask - remove unnecessary setting of dev->base_addr Signed-off-by: Jeff Garzik commit 94f1ff1eee801b02abb14f35debd2094760ed9c3 Author: Jeff Garzik Date: Fri Nov 23 21:23:36 2007 -0500 [netdrvr] netxen: checkpatch fixes (98% trim trailing whitespace) Signed-off-by: Jeff Garzik commit ff9754bba5e0ef14dea3af5930a9ee8d356ebcea Author: Peter Korsgaard Date: Thu Nov 15 11:10:12 2007 +0100 dm9601: Consolidate common parts of dm_write_*_async dm_write_async and dm_write_reg_async are almost identical. Move common functionality to dm_write_async_helper (saves ~256b). Signed-off-by: Peter Korsgaard Signed-off-by: Jeff Garzik commit 880375217a3a776f992c4bb98abebe0d7b4ff650 Author: Alan Cox Date: Mon Nov 19 15:03:38 2007 +0000 slip: Drag kicking and screaming into coding style compliance Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 73c37a0118311ee4867849a6a80364a953c14cec Author: Alan Cox Date: Mon Nov 19 15:02:32 2007 +0000 3c501: Bring into compliance with the coding style 3c501 leads the way... 8) Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik commit 27b8baddad24fa6dc4502001f34088f58008e7b2 Author: Adrian Bunk Date: Wed Nov 21 15:02:55 2007 -0800 drivers/net/chelsio/: #if 0 unused functions This patch #if 0's the following unused functions: - espi.c:t1_espi_set_misc_ctrl() - sge.c:t1_sched_set_max_avail_bytes() - sge.c:t1_sched_set_drain_bits_per_us() Signed-off-by: Adrian Bunk Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 9908580ccfe9e58ed48d466c5a79cb51dcd1b926 Author: Joe Perches Date: Mon Nov 19 17:48:28 2007 -0800 drivers/net: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit 373d0592e06656960fa15085f8f5a3ba72a99ad7 Author: Joe Perches Date: Mon Nov 19 17:48:25 2007 -0800 drivers/net/sk98lin: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit 5e899adfd65994ead80e0f934c5e14d19892b4b0 Author: Joe Perches Date: Mon Nov 19 17:48:26 2007 -0800 drivers/net/wan: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit 1f02d0223e6f22bf772ab9822f1e6ba01db9078c Author: Joe Perches Date: Mon Nov 19 17:48:24 2007 -0800 drivers/net/netxen: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit 9e90e0d37da1d72a6bc80b6b411a46aab81fb2af Author: Joe Perches Date: Mon Nov 19 17:48:23 2007 -0800 drivers/net/ixgb: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit db2b3926e4bf4bb1d0e02e1b1740c57c1f44f7b8 Author: Joe Perches Date: Mon Nov 19 17:48:22 2007 -0800 drivers/net/cxgb3: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit 997761d7c3e496a444d16550c5f46a40ecf4c299 Author: Joe Perches Date: Mon Nov 19 17:48:21 2007 -0800 drivers/net/chelsio: Add missing "space" Signed-off-by: Joe Perches Signed-off-by: Jeff Garzik commit a81a03dc81561f63f135fcaa932b246beaee7001 Author: Eliezer Tamir Date: Thu Nov 15 20:09:02 2007 +0200 add bnx2x driver for BCM57710 Signed-off-by: Eliezer Tamir Signed-off-by: David S. Miller commit b39bdc9eb6581ad074fe2f03250c6cb5e969bbdf Author: Sreenivasa Honnur Date: Wed Nov 14 01:42:25 2007 -0800 [S2IO]: Support for add/delete/store/restore ethernet addresses - Support to add/delete/store/restore 64 and 128 Ethernet addresses for Xframe I and Xframe II respectively. Signed-off-by: Sreenivasa Honnur Signed-off-by: David S. Miller commit 2b457753cc3cd2fc3157c6768bf5b0e05a9b68a7 Author: Patrick McHardy Date: Tue Nov 13 20:54:59 2007 -0800 [E1000]: Secondary unicast address support Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses. Signed-off-by: Patrick McHardy Signed-off-by: Auke Kok Signed-off-by: David S. Miller commit d22c674cc5d4e058f6c8df9814e64baeed7b306c Author: Joe Perches Date: Tue Nov 13 20:53:51 2007 -0800 [E1000E]: convert register test macros to functions Add functions for reg_pattern_test and reg_set_and check Changed macros to use these functions Compiled x86, untested Size decreased ~2K old: $ size drivers/net/e1000e/ethtool.o text data bss dec hex filename 14461 0 0 14461 387d drivers/net/e1000e/ethtool.o new: $ size drivers/net/e1000e/ethtool.o text data bss dec hex filename 12498 0 0 12498 30d2 drivers/net/e1000e/ethtool.o Signed-off-by: Joe Perches Signed-off-by: Auke Kok Signed-off-by: David S. Miller commit 7649ddf7147669b8836d3a38ad1d85412c3a4d16 Author: Joe Perches Date: Tue Nov 13 20:52:05 2007 -0800 [E1000]: Convert regtest macro's to functions Minimal macro to function conversion in e1000_ethtool.c Adds functions reg_pattern_test and reg_set_and_check Changes REG_PATTERN_TEST and REG_SET_AND_CHECK macros to call these functions. Saves ~2.5KB Compiled x86, untested (no hardware) old: $ size drivers/net/e1000/e1000_ethtool.o text data bss dec hex filename 16778 0 0 16778 418a drivers/net/e1000/e1000_ethtool.o new: $ size drivers/net/e1000/e1000_ethtool.o text data bss dec hex filename 14128 0 0 14128 3730 drivers/net/e1000/e1000_ethtool.o Signed-off-by: Joe Perches Signed-off-by: Auke Kok Signed-off-by: David S. Miller commit af1710a493c5cb668c38d4008340443039809790 Author: Auke Kok Date: Tue Nov 13 20:49:15 2007 -0800 [E1000]: update netstats traffic counters realtime formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see. Signed-off-by: Auke Kok Signed-off-by: David S. Miller commit 94e3b7161fdbbc79221fda7a8bbff822fec77245 Author: Auke Kok Date: Tue Nov 13 20:48:36 2007 -0800 [E1000E]: update netstats traffic counters realtime formerly e1000/e1000e only updated traffic counters once every 2 seconds with the register values of bytes/packets. With newer code however in the interrupt and polling code we can real-time fill in these values in the netstats struct for users to see. Signed-off-by: Auke Kok Signed-off-by: David S. Miller commit b6b0faa95628f852415b01a17ef00a10d57dc916 Author: Jay Vosburgh Date: Tue Nov 13 20:25:48 2007 -0800 [BONDING]: Documentation update Update the bonding documentation: more discussion on initialization and configuration, changes to discussion of packet reordering in balance-rr, update some out of date information. Based in part on input from Rick Jones and Andy Gospodarek . Signed-off-by: Jay Vosburgh Acked-by: Andy Gospodarek Signed-off-by: David S. Miller commit 17a94df58351afdb2d57acbb39b1b1334f7cf77e Author: Sten Wang Date: Mon Nov 12 21:31:11 2007 -0800 [NET]: Add support for the RDC R6040 Fast Ethernet controller This patch adds support for the RDC R6040 MAC we can find in the RDC R-321x System-on-chips. Signed-off-by: Sten Wang Signed-off-by: Daniel Gimpelevich Signed-off-by: Florian Fainelli commit bddf783a68d41d4a22ab3e8710a297fe85d84024 Author: David Acker Date: Thu Nov 8 10:17:41 2007 -0800 Fix e100 on systems that have cache incoherent DMA On the systems that have cache incoherent DMA, including ARM, there is a race condition between software allocating a new receive buffer and hardware writing into a buffer. The two race on touching the last Receive Frame Descriptor (RFD). It has its el-bit set and its next link equal to 0. When hardware encounters this buffer it attempts to write data to it and then update Status Word bits and Actual Count in the RFD. At the same time software may try to clear the el-bit and set the link address to a new buffer. Since the entire RFD is once cache-line, the two write operations can collide. This can lead to the receive unit stalling or interpreting random memory as its receive area. The fix is to set the el-bit on and the size to 0 on the next to last buffer in the chain. When the hardware encounters this buffer it stops and does not write to it at all. The hardware issues an RNR interrupt with the receive unit in the No Resources state. Software can write to the tail of the list because it knows hardware will stop on the previous descriptor that was marked as the end of list. Once it has a new next to last buffer prepared, it can clear the el-bit and set the size on the previous one. The race on this buffer is safe since the link already points to a valid next buffer and the software can handle the race setting the size (assuming aligned 16 bit writes are atomic with respect to the DMA read). If the hardware sees the el-bit cleared without the size set, it will move on to the next buffer and skip this one. If it sees the size set but the el-bit still set, it will complete that buffer and then RNR interrupt and wait. Signed-off-by: David Acker Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik commit 4f166117bd6ea09dd8425334eb53930fff6c636f Author: Francois Romieu Date: Thu Nov 1 00:52:13 2007 -0700 sundance: SIOCDEVPRIVATE pollution To quote one of my favorite contemporary author: [include/linux/sockios.h] * THESE IOCTLS ARE _DEPRECATED_ AND WILL DISAPPEAR IN 2.5.X -DaveM */ #define SIOCDEVPRIVATE 0x89F0 /* to 89FF */ [...] Gentoo's snmpd trips up over this code when trying to figure if the driver supports the non-SIOCDEVPRIVATE API or not. One can argue over its choice of heuristic but there no reason to make ioctl more ugly than needed. Signed-off-by: Francois Romieu Cc: Jesse Huang Tested-by: Volker Sauer Cc: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik commit 1f02ee3657a1791e3d49685bf8fc5467479c37ab Author: Adrian Bunk Date: Mon Nov 5 18:07:31 2007 +0100 drivers/net/netxen/: cleanups This patch contains the following cleanups: - static functions in .c files shouldn't be marked inline - make needlessly global code static - #if 0 unused code Signed-off-by: Adrian Bunk Signed-off-by: Jeff Garzik commit 8c0fff1313d15d06271c263a97e0806f644ee793 Author: Auke Kok Date: Wed Oct 31 15:22:10 2007 -0700 ixgbe: Fix copper PHY initialization code While cleaning up the internal API focussing on Fiber and CX4 code we found that I had broken the copper PHY initialization code. This patch restores the PHY-specific code. This is mostly uninteresting since no copper PHY boards are yet available. The changes have been tested against Fiber only as I do not even have copper PHY versions of 82598 macs. This change actually cleans up the API code a bit more and we lose some initialization code. A few PHY link detection helper lines of code have been snuck into this patch, as well as a read flush where it was suspected that this might cause issues. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik commit b3637100199b2679cd2f39d47a0061a3398cd3ca Author: Auke Kok Date: Wed Oct 31 15:22:05 2007 -0700 e1000/e1000e: Move PCI-Express device IDs over to e1000e e1000e will from now on support the PCI-Express adapters that previously were supported by e1000. This support means better performance and easier debugging from now on for both the old PCI-X/PCI hardware and PCI-Express adapters. This patch also moves 3 recently merged device IDs over to e1000e that are identical to quad-port versions of already existing dual port versions. With this last bit every former e1000 pci-e device should work now with e1000e. Here is a brief list of which gigabit driver to use with which adapter: e1000: 82540 -> 82547 e1000e: 82571 -> 82573 ich8, ich9 (82562 or 82566) es2lan (80003eslan) igb: (not yet merged, only available from e1000.sf.net) 82575 Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik commit 5826a48726ebf8a35446c0419a7c96026c9656b4 Author: Auke Kok Date: Wed Oct 31 15:22:00 2007 -0700 e1000e: Disable L1 ASPM power savings for 82573 mobile variants L1 ASPM link (pci-e link power savings) has significant benefits (~1W savings when link is active) but unfortunately does not work correctly on any of the chipsets that have 82573 on mobile platforms which causes various nuisances: - eeprom reads return garbage information leading to bad eeprom checksums - long ping times (up to 2 seconds) - complete system hangs (freeze/lockup) A lot of T60 owners have been plagued by this, but other mobile solutions also suffer from these symptoms. Disabling L1 ASPM before we activate the PCI-E link fixes all of these issues at the cost of some power consumption. Remove a workaround RDTR adjustment that is no longer needed with this new one. Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik commit b59e45f3478564f62bc461bdd57ed9ef0fb9fd9f Author: Bill Hayes Date: Wed Oct 31 15:21:52 2007 -0700 e1000e: alternate MAC address support Port alternate MAC address support from the sourceforge e1000 driver to the upstream e1000e driver. Signed-off-by: Bill Hayes Signed-off-by: Auke Kok Signed-off-by: Jeff Garzik commit cfddf40121e3e17858ace1fd1a6ad59acb1469cc Author: Jeff Garzik Date: Sun Nov 4 21:53:26 2007 -0500 [netdrvr] ibmlana: move away from legacy MCA API Signed-off-by: Jeff Garzik commit 890dd3b533d12956f113c87762160b66c667cf1f Author: Jeff Garzik Date: Sun Nov 4 21:52:49 2007 -0500 [netdrvr] ibmlana: modularization cleanup * move alloc_netdev() call, register_netdev() call, and associated failure cleanup into ibmlana_probe() * move per-net_device cleanup into ibmlana_remove_one() Signed-off-by: Jeff Garzik commit 52a1b77a1e1e2f2bb0aa06d69257751de7629a3f Author: Jeff Garzik Date: Mon Oct 29 05:46:16 2007 -0400 [netdrvr] irq handler minor cleanups in several drivers * use irq_handler_t where appropriate * no need to use 'irq' function arg, its already stored in a data struct * rename irq handler 'irq' argument to 'dummy', where the function has been analyzed and proven not to use its first argument. * remove always-false "dev_id == NULL" test from irq handlers * remove pointless casts from void* * declance: irq argument is not const * add KERN_xxx printk prefix * fix minor whitespace weirdness Signed-off-by: Jeff Garzik commit 946e8514e1956caeb1af1f42e13961721afa3537 Author: Jeff Garzik Date: Mon Oct 29 05:20:44 2007 -0400 hamradio/scc: kill unnecessary use of 'irq' function arg Signed-off-by: Jeff Garzik commit 7bb195235dfbab049350ceda319ccbaf6215cf00 Author: Alejandro Martinez Ruiz Date: Thu Oct 18 10:22:02 2007 +0200 sk98lin: kill bogus check and convert to use ARRAY_SIZE() This converts uses of ARRAY_SIZE(), and while at it also kills unreachable code as far as I can say. I can't tell what was the author trying to do with the following check. First we have: PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES]; and then a check goes like this: if (SK_PNMI_MAX_IDX != (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) with the second line being just ARRAY_SIZE(StatAddr), which will always return SK_PNMI_MAX_IDX, rendering the check useless. Signed-off-by: Alejandro Martinez Ruiz Signed-off-by: Jeff Garzik commit 98f2ede75e609281e899c5f02524a0d1126e72ff Author: Alejandro Martinez Ruiz Date: Thu Oct 18 10:16:33 2007 +0200 netdev: ARRAY_SIZE() cleanups Convert array size calculations to use ARRAY_SIZE(). Signed-off-by: Alejandro Martinez Ruiz Signed-off-by: Jeff Garzik commit 7821a95dc209546adec547a74b41dc0893011cb0 Author: Alejandro Martinez Ruiz Date: Thu Oct 18 10:00:15 2007 +0200 netdev: use ARRAY_SIZE() instead of sizeof(array) / ETH_GSTRING_LEN Using ARRAY_SIZE() on arrays of the form array[][K] makes it unnecessary to know the value of K when checking its size. Signed-off-by: Alejandro Martinez Ruiz Signed-off-by: Jeff Garzik commit 1ea672beb0aef10c1ad94f8368dfdb71463850cd Author: Roel Kluin <12o3l@tiscali.nl> Date: Fri Oct 26 21:51:26 2007 +0200 wireless: fix '!x & y' typo's Fix priority mistakes similar to '!x & y' Signed-off-by: Roel Kluin <12o3l@tiscali.nl> Signed-off-by: John W. Linville commit 0ea87df2db749fc567ed112f6da8eb27a39b3ae4 Author: Holger Schurig Date: Fri Oct 26 10:12:14 2007 +0200 libertas: move wlan_*_association_work from header to c file Move wlan_postpone_association_work() and wlan_cancel_association_work() from a assoc.h file to the sole user, into wext.c. Renamed those two functions to to libertas_XXX as well. Signed-off-by: Holger Schurig Acked-by: Dan Williams Signed-off-by: John W. Linville commit 95e3df424568e4ca74ba863e56c10916dc69cfcd Author: Jes Sorensen Date: Fri Oct 26 16:10:39 2007 +0200 iwlwifi: disable interrupts before calling request_irq Disable interrupts in the iwl4965 before calling request_irq() for the case that the previous OS or the BIOS left a pending interrupt in the chip. This behavior has been observed on some laptops such as T61 Thinkpads and Toshiba Portege R500 Signed-off-by: Jes Sorensen Signed-off-by: John W. Linville commit ae8550af4ff56e5bf6e25ef5295a7971c954b363 Author: Dmitry Torokhov Date: Fri Nov 2 01:55:36 2007 -0400 P54: use temporary variables to reduce size of generated code When there are 2 linked structures, using a temporary variable to hold a pointer to the often used structure usually produces better code (smaller and faster) since compiler does not have to constantly re-fetch data from the first structure. Signed-off-by: Dmitry Torokhov Signed-off-by: John W. Linville commit 17951539b2ad0ecd07a92ccd508573eff20bcd64 Author: Matthias Kaehlcke Date: Mon Nov 5 09:41:01 2007 +0100 Prism54: Convert mgmt_sem to the mutex API Signed-off-by: Matthias Kaehlcke Signed-off-by: John W. Linville commit 45eecb60e3fd133fda66a689d102128799a30700 Author: Dan Williams Date: Wed Oct 10 23:56:25 2007 -0400 orinoco: more reliable scan handling Bring scan result handling more in line with drivers like ipw. Scan results are aggregated and a BSS dropped after 15 seconds if no beacon is received. This allows the driver to interact better with userspace where more than one process may request scans or results at any time. Signed-off-by: Dan Williams Signed-off-by: John W. Linville commit 668b2d2f9a10965db5e4f1c87402657fb6e61fa3 Author: Michael Buesch Date: Sun Oct 28 16:29:32 2007 +0100 b43: consistent naming for ieee80211_ops Use a consistent naming scheme for the ops. Signed-off-by: Michael Buesch Cc: Larry Finger Signed-off-by: John W. Linville commit 797da6bb77b4e2f4dc5c1358106db4ba193c4ec5 Author: Michael Buesch Date: Sun Oct 28 16:19:44 2007 +0100 b43: Use the retry limit parameters from mac80211 Use the limits provided by mac80211. Signed-off-by: Michael Buesch Cc: Larry Finger Signed-off-by: John W. Linville commit 351a28cf9cf0903240e96d6d76849425c9460dd6 Author: Michael Buesch Date: Sun Oct 28 15:59:58 2007 +0100 b43: Dereference of wl->current_dev must be protected by wl->mutex Put all access to wl->current_dev under protection of the mutex. Signed-off-by: Michael Buesch Cc: Larry Finger Signed-off-by: John W. Linville commit 324ba82b54d5a57a9a6a8ac503134934eafcb157 Author: Michael Buesch Date: Sun Oct 28 21:08:51 2007 +0100 b43legacy: Remove set_key callback We don't need the set_key callback, as we don't do hw crypto. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville commit c886b8b31489d1bce55781bece850f9f4dae6331 Author: Larry Finger Date: Thu Oct 11 00:05:57 2007 -0500 b43legacy: Rewrite pwork locking Implement much easier and more lightweight locking for the periodic work. This also removes the last big busywait loop and replaces it by a sleeping loop. This patch for b43legacy is patterned aftar the same patch for b43 by Michael Buesch . Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit fc4cd8aa5b80179a8e2ed540b81706878e0a4c7c Author: Larry Finger Date: Wed Oct 10 22:48:17 2007 -0500 b43legacy: Use input-polldev for the rfkill switch This removes the direct call to rfkill on an rfkill event and replaces it with an input device. This way userspace is also notified about the event. This patch is the port to b43legacy of a patch for b43 by Michael Buesch . Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit dacf3054a49cd9d5622d8b05291453421f254743 Author: Larry Finger Date: Wed Oct 10 22:44:22 2007 -0500 b43legacy: RF-kill support This adds full support for the RFKILL button and the RFKILL LED trigger. This is a port to b43legacy of a patch by Michael Buesch for b43. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit 4b9d1f07b79e5b72af537524599fb27d779ee359 Author: Larry Finger Date: Fri Oct 12 23:04:51 2007 -0500 b43legacy: LED triggers support Drive the LEDs through the generic LED triggers. The patch to b43 by Michael Buesch has been ported to b43legacy. Signed-off-by: Larry Finger Signed-off-by: John W. Linville commit a8512aef5415159adef23fde2c561cc5d17d8a5d Author: Christoph Hellwig Date: Thu Oct 25 17:15:51 2007 +0800 iwlwifi: cleanup Kconfig and ifdefs to split 3945 and 4965 Currently the iwl3945 & iwl4965 drivers share some common Kconfig symbols. This split it up into options for the individual drivers and gets rid of all the CONFIG_IWLWIFI cruft. Signed-off-by: Christoph Hellwig Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 3707035e5020b1247757d0d4596533cfcb53ec89 Author: Christoph Hellwig Date: Thu Oct 25 17:15:50 2007 +0800 iwlwifi: keep 3945 and 4965 headers separate The iwl3945 and iwl4965 devices share some common structure, but with a lot of difference split all over. Currently the two drivers share a lot of headers and use ugly preprocessor magic to manage the difference. This patch keeps two entirely separate copies of the headers to get rid of these hacks an ease future development. Signed-off-by: Christoph Hellwig Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 78af19b7ad9e7134539b760bd5fadc8ec6f9ad20 Author: Christoph Hellwig Date: Thu Oct 25 17:15:49 2007 +0800 iwlwifi: mark more functions/variables static mark more functions/variables static Signed-off-by: Christoph Hellwig Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 55516cdfa885d1ff8da105e6ef6b0f099d65ca7b Author: Zhu Yi Date: Thu Oct 25 17:15:48 2007 +0800 iwlwifi: Update iwlwifi version stamp to 1.1.19 Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 86ba5dcc8296762259a5855185fb248ecfb65484 Author: Zhu Yi Date: Thu Oct 25 17:15:44 2007 +0800 iwlwifi: Update iwlwifi version stamp to 1.1.18 Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 87bc26af86e2be8e177d05ba68bfb0df36403c46 Author: mabbas Date: Thu Oct 25 17:15:42 2007 +0800 iwl4965: exclude 60M rate from probe request This patch do the following 2 things: 1. Make sure we don't add rate 60M part of supported rate in proble request, some AP does not like that. 2. It is wrong to set priv->active_rate in this function, this will set it to all avialable rates which might overwrite the mode supported rate. priv->active_rate should be set by only from iwl_set_rate. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit eef6507515aca0c45cc1c03b8c9a83379b146645 Author: Tomas Winkler Date: Thu Oct 25 17:15:41 2007 +0800 iwlwifi: Renames struct fw_image_desc to struct fw_desc This patche shortens the name of struct fw_image_desc to be struct fw_desc. Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 9d212ac79a714dcc6731a9deba121203c7f98eb6 Author: Emmanuel Grumbach Date: Thu Oct 25 17:15:40 2007 +0800 iwlwifi: add 5965 SCD registers to iwl-prph.h This patch adds SCD registers for 5965 Signed-off-by: Emmanuel Grumbach Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit e63a3e7d5982098911ac99fd0a5a9f3acd564465 Author: Emmanuel Grumbach Date: Thu Oct 25 17:15:39 2007 +0800 iwlwifi: move 3945 SCD registers to iwl-prph.h This patch moves 3945 SCD registers to iwl-prph.h. These registers are assigned from the periphery bus Signed-off-by: Emmanuel Grumbach Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit a376ab1c76c42aaa2d4818a07d81f61a70ed0e7b Author: Emmanuel Grumbach Date: Thu Oct 25 17:15:38 2007 +0800 iwlwifi-ht: move 4965 SCD registers to iwl-prph.h This patch moves 4965 SCD registers to iwl-prph.h. These registers are assigned from the periphery bus Signed-off-by: Emmanuel Grumbach Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 2fe388d4ea020ecde3602013ab1a86a0f6878008 Author: Tomas Winkler Date: Thu Oct 25 17:15:37 2007 +0800 iwlwifi: replacing wording restricted to nic access in iwl-io This patch replaces wording 'restricted' with more appropriate 'nic access' NIC access is grabbed to prevent NIC entering power save mode General cleanup of iwl-io.h Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit 946a2c4fd50f4d1484e45513d90b7e310b17241a Author: Tomas Winkler Date: Thu Oct 25 17:15:36 2007 +0800 iwlwifi: rename restricted_mem to targ_mem This patch renames restricted_mem suffix with more proper name targ_mem for function accessing memory on the nic in target mode Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit 8541997236e08d7fa79e020ad8ad6ee6fb45e9d6 Author: Tomas Winkler Date: Thu Oct 25 17:15:35 2007 +0800 iwlwifi: replace restricted_reg with prph This patch renames restricted_reg suffix with more proper name prhp for function accessing registers on the periphery bus. Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit 9587c3d3e848d06c0c3f44dd7f5691c44dca0ae5 Author: mabbas Date: Thu Oct 25 17:15:34 2007 +0800 iwlwifi: accept up to 4K frame size on Rx side to fit A-MSDU frame The driver drops any Rx frame larger than 2332 bytes, but with A-MSDU frame, it could be up to 4K. This patch makes sure we can process larger A-MSDU frame. Signed-off-by: Mohamed Abbas Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit cf97c3cf53516b36063783d39152b7af5f2d36b9 Author: Tomas Winkler Date: Thu Oct 25 17:15:32 2007 +0800 iwlwifi: using PCI_DEVICE macro PCI_DEVICE macro is more concise when using defualt values in device definitions Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit b10b3f0b9ae231cf083a8559f6596d36c5a1b662 Author: Tomas Winkler Date: Thu Oct 25 17:15:31 2007 +0800 iwlwifi: remove cck_power_index_compensation cck_power_index_compensation variable was never used Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit de157c340374cd8a3bde058f8b51d4e6b93dbadc Author: Ian Schram Date: Thu Oct 25 17:15:30 2007 +0800 iwlwifi: remove late null-check and duplicate bug_on These pieces of code appear to be useless. The BUG_ON is also performed in iwl_send_cmd_async. Serious karma would be needed to enter iwl_ativate_qos with a null priv. I had a deja vu when patching this, but for the life of me I couldn't track down a similar patch. Signed-off-by: Ian Schram Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 183aae2ad0688f1ebd2dd9c2a63167058b3be662 Author: Ian Schram Date: Thu Oct 25 17:15:29 2007 +0800 iwlwifi: Beautify by removing superfluous newlines and code Moving code around, lindent, and whatnot created several places where there appeared to be an 75 column "rule" instead of 80. This patch removes those that I can spot, hopefully increasing readability. Signed-off-by: Ian Schram Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 1d2cf7296d921bcfb7bc609c7d024067fc9ba102 Author: Ian Schram Date: Thu Oct 25 17:15:28 2007 +0800 iwlwifi: Two comments in iwl-3945.c were longer than 80 columns This patch shorten two comments lines in iwl-3945.c Signed-off-by: Ian Schram Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 341e9aa19ff10889b468866d0b2ea88bcd2efa55 Author: Tomas Winkler Date: Thu Oct 25 17:15:27 2007 +0800 iwlwifi: remove cck_flag from iwl_driver_hw_info This patch remove cck_flag from iwl_driver_hw_info, this flag is unused after spliting the iwl-base.c Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 9e44f3d59756346fa78ff589e7b12552aa279dce Author: Tomas Winkler Date: Thu Oct 25 17:15:26 2007 +0800 iwlwifi: add TGN flag to qos parameters This patch adds TGN flag to QoS parameters. This flag governs enablement of NAV shortening with CF-End and filters in 4 or 8K RX AMSDU packets Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit d75b603b27fb0cfc1302802a0fcd0ff9d4628ded Author: Tomas Winkler Date: Thu Oct 25 17:15:25 2007 +0800 iwlwifi: rs-4965 fix return values This patch cleans up style of 'return' of rate scale 4965 functions. It renames return name variables rc to ret, change functions to void if no meaningful value was returned it add return of -EINVAL for checks of wrong arguments. Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit ec4981016e9916b1172d9df8997a30d9fb602458 Author: Tomas Winkler Date: Thu Oct 25 17:15:24 2007 +0800 iwlwifi: renaming last_used and first_empty This patch renames queue pointers to write_ptr and read_ptr instead of first_empty and last_used. This is closer to technical terminology we everyday use Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit 83633ce37e1dbd501a31a6604bfa996c314f986f Author: Ian Schram Date: Thu Oct 25 17:15:23 2007 +0800 iwlwifi: rename iwl_eeprom_aqcuire_semaphore to _acquire_ Correct the spelling of aqcuire. Signed-off-by: Ian Schram Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit b160caa2bddd02b7a5031046aa566546ade9597a Author: Ian Schram Date: Thu Oct 25 17:15:22 2007 +0800 iwlwifi: fix various spelling and typos Fixing various spelling errors and typos. Mostly in comments. In total 27 words were corrected, some of which occurred more than ones. Signed-Of-By: Ian Schram Signed-off-by: Zhu Yi Signed-off-by: John W. Linville commit 422f35c440d9a2798409130b834192f9cbd74200 Author: Tomas Winkler Date: Tue Oct 16 00:50:25 2007 +0200 iwlwifi: Add erp_ie_changed hanlder This patch adds erp_ie_changed handler to iwl4956 Signed-off-by: Tomas Winkler Signed-off-by: John W. Linville commit c71f05daf3a61a30cc7127cec097c05412f767ca Author: Ivo van Doorn Date: Sat Oct 27 13:44:08 2007 +0200 rt2x00: Release rt2x00 2.0.12 Version bump. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit f179623d639f5065df52c232ab3347de551a50a8 Author: Mattias Nissler Date: Sat Oct 27 13:43:49 2007 +0200 rt2x00: Correctly set ACK bit in tx descriptors Add a flag to struct txdata_entry_desc that specifies whether an ack for the frame is to be expected. Use this flag to set the ACK bit in the tx descriptor. Previously, the ACK bit could be set incorrectly on CTS-to-self frames, so they caused retries and were reported to be failed in the txdone handlers. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit e4b5a0e76aaab780f8b22dee76885a3b039253a1 Author: Adam Baker Date: Sat Oct 27 13:43:29 2007 +0200 rt2x00: Place mutex around USB register access There is a buffer, csr_cache which is used to hold copies of data being passed to the USB stack which can get corrupted if multiple threads attempt to access CSR registers simultaneously. There is also the possibility if multiple threads try to access BBP or RF registers for the multiple USB operations needed to get interleaved leading to incorrect results. This patch introduces a mutex to prevent such simultaneous access. The interleaved access problem may also affect the PCI devices but if so that will be handled in a follow-up patch. Signed-off-by: Adam Baker Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 89b64ef8cddda4bdc8f5e6cadca3741ed50ea8d0 Author: Ivo van Doorn Date: Sat Oct 27 13:43:06 2007 +0200 rt2x00: Remove data_desc structure Coverty indicated that data_desc with a single element array is bad coding style. This removes the structure and forces everybody to use __le32. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit d6d6afe95c5b3f6f6639dcc21edf05569a9bae57 Author: Mattias Nissler Date: Sat Oct 27 13:42:37 2007 +0200 rt2x00: Rework rt73 antenna selection This patch changes rt73 antenna selection to what I believe is the correct way. It also fixes a small selection bug that switched the antennas by accident. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit ffd5418ef575035ee8e9cdaa48224befffdfbeb7 Author: Ivo van Doorn Date: Sat Oct 27 13:42:18 2007 +0200 rt2x00: Remove unused variables With the updated antenna setup the following variables are no longer used. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit c6880df677265eae91cd98214d37c27067ab080e Author: Mattias Nissler Date: Sat Oct 27 13:41:53 2007 +0200 rt2x00: Rework rt61 antenna selection. This patch changes rt61 antenna selection again. It helps at least with the rt61 pci card in my box, I hope I haven't broken behaviour on other RF chips. RF 2529 antenna setup is incomplete, we need to at code for diversity when we figure out how it is done properly. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit a320f7239aaa248a49f4a1264c6ca7f1b89cfcbf Author: Adam Baker Date: Sat Oct 27 13:41:25 2007 +0200 rt2x00: Unconstify rt2x00dev Some register accesses need rt2x00dev to be non-const they all need modifying so the prototype is consistent. Signed-off-by: Adam Baker Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 143cec7430e62dba7381f3e2ba3d89e39012d815 Author: Ivo van Doorn Date: Sat Oct 27 13:40:51 2007 +0200 rt2x00: Detect initial rfkill state on register When registering rfkill, make sure a initial poll event is directly executed to detect the initial rfkill state and send the event to the rfkill layer. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 5fa0e7ee33b994194abc4c70c20cd31820343bf2 Author: Ivo van Doorn Date: Sat Oct 27 13:40:25 2007 +0200 rt2x00: Input-polldev requires input device input-polldev requires a correctly allocated and initialized input device to be set for the input_polled_dev->input field. Failure to do that will prevent correct polling of the device. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit b4564827825c95e02ea9ea0e21c730ae69a9bff8 Author: Ivo van Doorn Date: Sat Oct 27 13:39:57 2007 +0200 rt2x00: Split rt61/rt73 antenna selection into RX and TX antenna Based on investigation of the legacy drivers, I have made the following assumptions of the antenna setup: - R77 is the TX antenna configuration - RF2529 fetches default antenna selection from NIC eeprom word With these assumptions we can change the antenna configuration to correctly read both antenna setup values and correctly configure the antenna. And we can now also configure the antenna for RF2529 without a double antenna. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 6fc60d92736f5ae3a4555b0c1470216ff33cdfcf Author: Ivo van Doorn Date: Sat Oct 27 13:39:28 2007 +0200 rt2x00: Disable RX when switching antenna Antenna switching will be ignored when RX is enabled during the switch. Make sure we disable the RX during the switch and don't forget to reenable it later. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 1ab057c7a75458d03f24b07ac244eeb54cdecb9d Author: Ivo van Doorn Date: Sat Oct 13 16:27:16 2007 +0200 [PATCH] rt2x00: Release rt2x00 2.0.11 Version bump. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 12bf02ca47938ab0be5b1a798e0fb68c19fcc088 Author: Mattias Nissler Date: Sat Oct 13 16:26:57 2007 +0200 [PATCH] rt2x00: Fix antenna selection. In the config() handler, make sure that we do configure an antenna if the current active antenna is uninitialized. Furthermore, don't overwrite the active antenna with bogus values if we didn't touch the antenna setup. Signed-off-by: Mattias Nissler Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit ac468032e926f5f754445da4ea141dd9ecc0386f Author: Ivo van Doorn Date: Sat Oct 13 16:26:42 2007 +0200 [PATCH] rt2x00: Cleanup if-statements Cleanup if-statements for simple 1/0 register field values. This also fixes a endian bug in rt2500usb when working with the PHY_CSR2 initialization. As well as a bug in the enabling of the LED in rt73usb. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit ce2426fc2622eb72e0b4b50769314bd7217720fa Author: Ivo van Doorn Date: Sat Oct 13 16:26:36 2007 +0200 [PATCH] rt2x00: Implement SW diversity When mac80211 indicates that the default antenna setup should be used _and_ that this default setup is SW_DIVERSITY. This requires sampling and storing the RSSI per antenna and check once every 2 seconds to determine if the RSSI has changed significantly. Once this is the case we should sample the other antenna for a short period and evaluate if we need to swap antenna or not. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 17e68d44e28eb07f22dc2a5a8674dfc4a97a7ae0 Author: Ivo van Doorn Date: Sat Oct 13 16:26:32 2007 +0200 [PATCH] rt2x00: Remove rt2x00_clear_link rt2x00_clear_link() was becoming too large for statically inline, also it was used on a single location and shouldn't really be used anywhere else. So move the entire code into the function rt2x00lib_start_link_tuner() Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 4cd6696eead719a1230d98cba3fdd3073d541fb9 Author: Ivo van Doorn Date: Sat Oct 13 16:26:27 2007 +0200 [PATCH] rt2x00: SW diversity should default to antenna B Although ANTENNA_SW_DIVERSITY should never be send to the driver, we should still handle it to prevent bugs. But instead of defaulting to ANTENNA_HW_DIVERSITY we should default to ANTENNA_B instead. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 62d667bfc91b59c525fe6c2a34ecfa7678bbdc59 Author: Ivo van Doorn Date: Sat Oct 13 16:26:23 2007 +0200 [PATCH] rt2x00: Correctly translate mac80211 antenna setup to rt2x00 mac80211 has 3 values for the antenna setup: 0 - default 1 - use antenna 1 2 - use antenna 2 This means that rt2x00 should store the default value from the EEPROM somwhere and use that when mac80211 indicates that the antenna setup is 0. This also implies that rt2x00 should no longer write the hw->config.antenna_sel_* values based on the EEPROM input. This also adds the basis in rt2x00lib for correct software diversity handling. By default rt2x00lib will now configure antenna B instead of hardware diversity. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 68281f7f4ae6ceb3f910ba06392ce81c3fd66ecf Author: Ivo van Doorn Date: Sat Oct 13 16:26:18 2007 +0200 [PATCH] rt2x00: Use enum defines When setting the default EEPROM values use the values from the enums instead of "magic" values. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville commit 864d53840594fefba0143f24ed41caa5e09e29e2 Author: Ivo van Doorn Date: Sat Oct 13 16:26:12 2007 +0200 [PATCH] rt2x00: Move quality statistics into seperate structure Move all link quality statistics variables into the link_qual structure. This cleans up the link structure and allows us to use it for more then just statistics. Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville Documentation/networking/bonding.txt | 204 +- MAINTAINERS | 10 +- arch/ia64/hp/sim/simeth.c | 5 - arch/powerpc/platforms/pasemi/Makefile | 2 +- arch/powerpc/platforms/pasemi/dma_lib.c | 487 ++ arch/powerpc/platforms/pasemi/pasemi.h | 1 + arch/ppc/8260_io/enet.c | 4 +- arch/ppc/8260_io/fcc_enet.c | 4 +- drivers/net/3c501.c | 232 +- drivers/net/3c507.c | 15 +- drivers/net/Kconfig | 22 + drivers/net/Makefile | 2 + drivers/net/amd8111e.c | 4 +- drivers/net/at1700.c | 5 +- drivers/net/b44.c | 8 +- drivers/net/bnx2x.c | 9064 ++++++++++++++++++++++ drivers/net/bnx2x.h | 1071 +++ drivers/net/bnx2x_fw_defs.h | 198 + drivers/net/bnx2x_hsi.h | 2176 ++++++ drivers/net/bnx2x_init.h | 564 ++ drivers/net/bnx2x_init_values.h | 6368 +++++++++++++++ drivers/net/bnx2x_reg.h | 4394 +++++++++++ drivers/net/cassini.c | 2 +- drivers/net/chelsio/cxgb2.c | 2 +- drivers/net/chelsio/espi.c | 2 + drivers/net/chelsio/espi.h | 1 - drivers/net/chelsio/sge.c | 4 + drivers/net/chelsio/sge.h | 2 - drivers/net/cpmac.c | 3 - drivers/net/cxgb3/cxgb3_main.c | 177 +- drivers/net/cxgb3/cxgb3_offload.c | 4 +- drivers/net/cxgb3/firmware_exports.h | 20 +- drivers/net/cxgb3/regs.h | 22 + drivers/net/cxgb3/sge.c | 89 +- drivers/net/cxgb3/t3_hw.c | 48 +- drivers/net/cxgb3/version.h | 4 +- drivers/net/cxgb3/xgmac.c | 10 +- drivers/net/declance.c | 6 +- drivers/net/e100.c | 132 +- drivers/net/e1000/e1000_ethtool.c | 86 +- drivers/net/e1000/e1000_main.c | 84 +- drivers/net/e1000e/82571.c | 11 +- drivers/net/e1000e/defines.h | 1 + drivers/net/e1000e/e1000.h | 1 - drivers/net/e1000e/ethtool.c | 89 +- drivers/net/e1000e/hw.h | 4 + drivers/net/e1000e/lib.c | 39 +- drivers/net/e1000e/netdev.c | 49 +- drivers/net/e1000e/param.c | 7 - drivers/net/e1000e/phy.c | 3 +- drivers/net/eexpress.c | 12 +- drivers/net/gianfar_sysfs.c | 50 +- drivers/net/hamradio/scc.c | 8 +- drivers/net/ibmlana.c | 192 +- drivers/net/irda/irport.h | 2 +- drivers/net/irda/smsc-ircc2.c | 17 +- drivers/net/irda/via-ircc.c | 12 +- drivers/net/ixgbe/ixgbe.h | 8 +- drivers/net/ixgbe/ixgbe_82598.c | 156 +- drivers/net/ixgbe/ixgbe_common.c | 12 +- drivers/net/ixgbe/ixgbe_ethtool.c | 3 +- drivers/net/ixgbe/ixgbe_main.c | 21 +- drivers/net/ixgbe/ixgbe_phy.h | 1 - drivers/net/ixgbe/ixgbe_type.h | 13 +- drivers/net/lp486e.c | 9 +- drivers/net/myri10ge/myri10ge.c | 2 +- drivers/net/netxen/netxen_nic.h | 30 +- drivers/net/netxen/netxen_nic_ethtool.c | 28 +- drivers/net/netxen/netxen_nic_hw.c | 31 +- drivers/net/netxen/netxen_nic_hw.h | 18 +- drivers/net/netxen/netxen_nic_init.c | 96 +- drivers/net/netxen/netxen_nic_isr.c | 15 +- drivers/net/netxen/netxen_nic_main.c | 35 +- drivers/net/netxen/netxen_nic_niu.c | 64 +- drivers/net/netxen/netxen_nic_phan_reg.h | 15 +- drivers/net/pasemi_mac.c | 934 ++-- drivers/net/pasemi_mac.h | 365 +- drivers/net/pcmcia/axnet_cs.c | 16 +- drivers/net/pcmcia/fmvj18x_cs.c | 7 +- drivers/net/pcnet32.c | 2 +- drivers/net/pppol2tp.c | 2 +- drivers/net/qla3xxx.c | 2 +- drivers/net/r6040.c | 1096 +++ drivers/net/rrunner.c | 2 +- drivers/net/s2io-regs.h | 16 +- drivers/net/s2io.c | 209 +- drivers/net/s2io.h | 14 +- drivers/net/sgiseeq.c | 239 +- drivers/net/sis900.c | 6 +- drivers/net/sk98lin/skgemib.c | 2 +- drivers/net/sk98lin/skgepnmi.c | 14 +- drivers/net/sk98lin/skgesirq.c | 2 +- drivers/net/sky2.c | 61 +- drivers/net/slip.c | 367 +- drivers/net/smc9194.c | 2 +- drivers/net/sundance.c | 26 - drivers/net/tehuti.c | 10 +- drivers/net/tulip/de4x5.c | 4 +- drivers/net/ucc_geth.c | 3 - drivers/net/usb/dm9601.c | 53 +- drivers/net/via-rhine.c | 2 +- drivers/net/wan/farsync.c | 11 +- drivers/net/wan/sdla.c | 5 +- drivers/net/wan/wanxl.c | 2 +- drivers/net/wireless/Makefile | 3 +- drivers/net/wireless/airo.c | 8 +- drivers/net/wireless/atmel.c | 3 +- drivers/net/wireless/b43/Makefile | 1 + drivers/net/wireless/b43/b43.h | 11 + drivers/net/wireless/b43/debugfs.c | 2 +- drivers/net/wireless/b43/dma.c | 32 +- drivers/net/wireless/b43/leds.c | 10 +- drivers/net/wireless/b43/lo.c | 8 +- drivers/net/wireless/b43/main.c | 219 +- drivers/net/wireless/b43/main.h | 2 +- drivers/net/wireless/b43/phy.c | 672 +-- drivers/net/wireless/b43/phy.h | 18 +- drivers/net/wireless/b43/tables.c | 103 +- drivers/net/wireless/b43/tables.h | 12 +- drivers/net/wireless/b43/wa.c | 666 ++ drivers/net/wireless/b43/wa.h | 7 + drivers/net/wireless/b43/xmit.c | 26 +- drivers/net/wireless/b43legacy/Kconfig | 16 + drivers/net/wireless/b43legacy/Makefile | 29 +- drivers/net/wireless/b43legacy/b43legacy.h | 18 +- drivers/net/wireless/b43legacy/debugfs.c | 2 +- drivers/net/wireless/b43legacy/ilt.c | 2 +- drivers/net/wireless/b43legacy/leds.c | 413 +- drivers/net/wireless/b43legacy/leds.h | 61 +- drivers/net/wireless/b43legacy/main.c | 380 +- drivers/net/wireless/b43legacy/main.h | 2 +- drivers/net/wireless/b43legacy/phy.c | 40 +- drivers/net/wireless/b43legacy/phy.h | 2 +- drivers/net/wireless/b43legacy/radio.c | 29 +- drivers/net/wireless/b43legacy/radio.h | 4 +- drivers/net/wireless/b43legacy/rfkill.c | 189 + drivers/net/wireless/b43legacy/rfkill.h | 59 + drivers/net/wireless/b43legacy/xmit.c | 25 +- drivers/net/wireless/hostap/hostap_hw.c | 2 +- drivers/net/wireless/ipw2100.c | 3 +- drivers/net/wireless/iwlwifi/Kconfig | 164 +- drivers/net/wireless/iwlwifi/iwl-3945-commands.h | 1639 ++++ drivers/net/wireless/iwlwifi/iwl-3945-debug.h | 152 + drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 616 ++- drivers/net/wireless/iwlwifi/iwl-3945-io.h | 431 + drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 154 +- drivers/net/wireless/iwlwifi/iwl-3945-rs.h | 41 +- drivers/net/wireless/iwlwifi/iwl-3945.c | 601 +- drivers/net/wireless/iwlwifi/iwl-3945.h | 986 +++- drivers/net/wireless/iwlwifi/iwl-4965-commands.h | 2562 ++++++ drivers/net/wireless/iwlwifi/iwl-4965-debug.h | 152 + drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 2062 +++++- drivers/net/wireless/iwlwifi/iwl-4965-io.h | 431 + drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 988 ++- drivers/net/wireless/iwlwifi/iwl-4965-rs.h | 91 +- drivers/net/wireless/iwlwifi/iwl-4965.c | 1275 ++-- drivers/net/wireless/iwlwifi/iwl-4965.h | 1214 +++- drivers/net/wireless/iwlwifi/iwl-channel.h | 161 - drivers/net/wireless/iwlwifi/iwl-commands.h | 1734 ----- drivers/net/wireless/iwlwifi/iwl-debug.h | 152 - drivers/net/wireless/iwlwifi/iwl-eeprom.h | 336 - drivers/net/wireless/iwlwifi/iwl-hw.h | 537 -- drivers/net/wireless/iwlwifi/iwl-io.h | 470 -- drivers/net/wireless/iwlwifi/iwl-priv.h | 308 - drivers/net/wireless/iwlwifi/iwl-prph.h | 61 +- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2983 ++++---- drivers/net/wireless/iwlwifi/iwl4965-base.c | 3548 +++++---- drivers/net/wireless/iwlwifi/iwlwifi.h | 708 -- drivers/net/wireless/libertas/11d.c | 96 +- drivers/net/wireless/libertas/11d.h | 26 +- drivers/net/wireless/libertas/README | 40 +- drivers/net/wireless/libertas/assoc.c | 265 +- drivers/net/wireless/libertas/assoc.h | 32 +- drivers/net/wireless/libertas/cmd.c | 354 +- drivers/net/wireless/libertas/cmdresp.c | 238 +- drivers/net/wireless/libertas/debugfs.c | 1375 +--- drivers/net/wireless/libertas/debugfs.h | 12 +- drivers/net/wireless/libertas/decl.h | 116 +- drivers/net/wireless/libertas/defs.h | 52 +- drivers/net/wireless/libertas/dev.h | 45 +- drivers/net/wireless/libertas/ethtool.c | 52 +- drivers/net/wireless/libertas/host.h | 70 +- drivers/net/wireless/libertas/hostcmd.h | 26 +- drivers/net/wireless/libertas/if_cs.c | 47 +- drivers/net/wireless/libertas/if_sdio.c | 51 +- drivers/net/wireless/libertas/if_sdio.h | 4 +- drivers/net/wireless/libertas/if_usb.c | 132 +- drivers/net/wireless/libertas/if_usb.h | 7 +- drivers/net/wireless/libertas/join.c | 202 +- drivers/net/wireless/libertas/join.h | 38 +- drivers/net/wireless/libertas/main.c | 563 +- drivers/net/wireless/libertas/rx.c | 68 +- drivers/net/wireless/libertas/scan.c | 274 +- drivers/net/wireless/libertas/scan.h | 96 +- drivers/net/wireless/libertas/tx.c | 45 +- drivers/net/wireless/libertas/types.h | 25 +- drivers/net/wireless/libertas/wext.c | 512 +- drivers/net/wireless/libertas/wext.h | 14 +- drivers/net/wireless/orinoco.c | 541 +- drivers/net/wireless/orinoco.h | 12 +- drivers/net/wireless/p54common.c | 2 +- drivers/net/wireless/p54pci.c | 77 +- drivers/net/wireless/prism54/isl_ioctl.c | 4 +- drivers/net/wireless/prism54/islpci_dev.c | 2 +- drivers/net/wireless/prism54/islpci_dev.h | 3 +- drivers/net/wireless/prism54/islpci_mgt.c | 4 +- drivers/net/wireless/rt2x00/rt2400pci.c | 173 +- drivers/net/wireless/rt2x00/rt2400pci.h | 24 +- drivers/net/wireless/rt2x00/rt2500pci.c | 141 +- drivers/net/wireless/rt2x00/rt2500pci.h | 4 +- drivers/net/wireless/rt2x00/rt2500usb.c | 206 +- drivers/net/wireless/rt2x00/rt2500usb.h | 17 +- drivers/net/wireless/rt2x00/rt2x00.h | 214 +- drivers/net/wireless/rt2x00/rt2x00config.c | 100 +- drivers/net/wireless/rt2x00/rt2x00debug.c | 240 +- drivers/net/wireless/rt2x00/rt2x00debug.h | 4 +- drivers/net/wireless/rt2x00/rt2x00dev.c | 301 +- drivers/net/wireless/rt2x00/rt2x00dump.h | 121 + drivers/net/wireless/rt2x00/rt2x00firmware.c | 5 - drivers/net/wireless/rt2x00/rt2x00lib.h | 8 + drivers/net/wireless/rt2x00/rt2x00mac.c | 7 +- drivers/net/wireless/rt2x00/rt2x00pci.c | 96 +- drivers/net/wireless/rt2x00/rt2x00pci.h | 12 +- drivers/net/wireless/rt2x00/rt2x00rfkill.c | 39 +- drivers/net/wireless/rt2x00/rt2x00ring.h | 37 +- drivers/net/wireless/rt2x00/rt2x00usb.c | 77 +- drivers/net/wireless/rt2x00/rt2x00usb.h | 19 +- drivers/net/wireless/rt2x00/rt61pci.c | 398 +- drivers/net/wireless/rt2x00/rt61pci.h | 14 +- drivers/net/wireless/rt2x00/rt73usb.c | 232 +- drivers/net/wireless/rt2x00/rt73usb.h | 14 +- drivers/net/wireless/rtl8187_dev.c | 2 + drivers/net/wireless/rtl8187_rtl8225.c | 8 +- drivers/net/wireless/wavelan.c | 2 +- drivers/net/wireless/wavelan_cs.c | 10 +- drivers/net/wireless/zd1211rw/Kconfig | 7 +- drivers/net/wireless/zd1211rw/Makefile | 3 +- drivers/net/wireless/zd1211rw/zd_chip.c | 126 +- drivers/net/wireless/zd1211rw/zd_chip.h | 60 +- drivers/net/wireless/zd1211rw/zd_def.h | 5 +- drivers/net/wireless/zd1211rw/zd_ieee80211.c | 196 +- drivers/net/wireless/zd1211rw/zd_ieee80211.h | 49 +- drivers/net/wireless/zd1211rw/zd_mac.c | 1535 ++--- drivers/net/wireless/zd1211rw/zd_mac.h | 117 +- drivers/net/wireless/zd1211rw/zd_netdev.c | 264 - drivers/net/wireless/zd1211rw/zd_netdev.h | 45 - drivers/net/wireless/zd1211rw/zd_rf.c | 5 +- drivers/net/wireless/zd1211rw/zd_rf.h | 5 +- drivers/net/wireless/zd1211rw/zd_rf_al2230.c | 5 +- drivers/net/wireless/zd1211rw/zd_rf_al7230b.c | 5 +- drivers/net/wireless/zd1211rw/zd_rf_rf2959.c | 5 +- drivers/net/wireless/zd1211rw/zd_rf_uw2453.c | 7 +- drivers/net/wireless/zd1211rw/zd_usb.c | 289 +- drivers/net/wireless/zd1211rw/zd_usb.h | 36 +- drivers/ssb/b43_pci_bridge.c | 1 + drivers/ssb/main.c | 10 +- drivers/ssb/pci.c | 221 +- include/asm-powerpc/pasemi_dma.h | 467 ++ include/linux/pci_ids.h | 3 + include/linux/ssb/ssb.h | 71 +- include/linux/ssb/ssb_regs.h | 59 +- net/ieee80211/ieee80211_wx.c | 2 +- 262 files changed, 50896 insertions(+), 18451 deletions(-) diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 6cc30e0..a0cda06 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -1,7 +1,7 @@ Linux Ethernet Bonding Driver HOWTO - Latest update: 24 April 2006 + Latest update: 12 November 2007 Initial release : Thomas Davis Corrections, HA extensions : 2000/10/03-15 : @@ -166,12 +166,17 @@ to use ifenslave. 2. Bonding Driver Options ========================= - Options for the bonding driver are supplied as parameters to -the bonding module at load time. They may be given as command line -arguments to the insmod or modprobe command, but are usually specified -in either the /etc/modules.conf or /etc/modprobe.conf configuration -file, or in a distro-specific configuration file (some of which are -detailed in the next section). + Options for the bonding driver are supplied as parameters to the +bonding module at load time, or are specified via sysfs. + + Module options may be given as command line arguments to the +insmod or modprobe command, but are usually specified in either the +/etc/modules.conf or /etc/modprobe.conf configuration file, or in a +distro-specific configuration file (some of which are detailed in the next +section). + + Details on bonding support for sysfs is provided in the +"Configuring Bonding Manually via Sysfs" section, below. The available bonding driver parameters are listed below. If a parameter is not specified the default value is used. When initially @@ -812,11 +817,13 @@ the system /etc/modules.conf or /etc/modprobe.conf configuration file. 3.2 Configuration with Initscripts Support ------------------------------------------ - This section applies to distros using a version of initscripts -with bonding support, for example, Red Hat Linux 9 or Red Hat -Enterprise Linux version 3 or 4. On these systems, the network -initialization scripts have some knowledge of bonding, and can be -configured to control bonding devices. + This section applies to distros using a recent version of +initscripts with bonding support, for example, Red Hat Enterprise Linux +version 3 or later, Fedora, etc. On these systems, the network +initialization scripts have knowledge of bonding, and can be configured to +control bonding devices. Note that older versions of the initscripts +package have lower levels of support for bonding; this will be noted where +applicable. These distros will not automatically load the network adapter driver unless the ethX device is configured with an IP address. @@ -864,11 +871,31 @@ USERCTL=no Be sure to change the networking specific lines (IPADDR, NETMASK, NETWORK and BROADCAST) to match your network configuration. - Finally, it is necessary to edit /etc/modules.conf (or -/etc/modprobe.conf, depending upon your distro) to load the bonding -module with your desired options when the bond0 interface is brought -up. The following lines in /etc/modules.conf (or modprobe.conf) will -load the bonding module, and select its options: + For later versions of initscripts, such as that found with Fedora +7 and Red Hat Enterprise Linux version 5 (or later), it is possible, and, +indeed, preferable, to specify the bonding options in the ifcfg-bond0 +file, e.g. a line of the format: + +BONDING_OPTS="mode=active-backup arp_interval=60 arp_ip_target=+192.168.1.254" + + will configure the bond with the specified options. The options +specified in BONDING_OPTS are identical to the bonding module parameters +except for the arp_ip_target field. Each target should be included as a +separate option and should be preceded by a '+' to indicate it should be +added to the list of queried targets, e.g., + + arp_ip_target=+192.168.1.1 arp_ip_target=+192.168.1.2 + + is the proper syntax to specify multiple targets. When specifying +options via BONDING_OPTS, it is not necessary to edit /etc/modules.conf or +/etc/modprobe.conf. + + For older versions of initscripts that do not support +BONDING_OPTS, it is necessary to edit /etc/modules.conf (or +/etc/modprobe.conf, depending upon your distro) to load the bonding module +with your desired options when the bond0 interface is brought up. The +following lines in /etc/modules.conf (or modprobe.conf) will load the +bonding module, and select its options: alias bond0 bonding options bond0 mode=balance-alb miimon=100 @@ -883,9 +910,10 @@ up and running. 3.2.1 Using DHCP with Initscripts --------------------------------- - Recent versions of initscripts (the version supplied with -Fedora Core 3 and Red Hat Enterprise Linux 4 is reported to work) do -have support for assigning IP information to bonding devices via DHCP. + Recent versions of initscripts (the versions supplied with Fedora +Core 3 and Red Hat Enterprise Linux 4, or later versions, are reported to +work) have support for assigning IP information to bonding devices via +DHCP. To configure bonding for DHCP, configure it as described above, except replace the line "BOOTPROTO=none" with "BOOTPROTO=dhcp" @@ -895,18 +923,14 @@ is case sensitive. 3.2.2 Configuring Multiple Bonds with Initscripts ------------------------------------------------- - At this writing, the initscripts package does not directly -support loading the bonding driver multiple times, so the process for -doing so is the same as described in the "Configuring Multiple Bonds -Manually" section, below. - - NOTE: It has been observed that some Red Hat supplied kernels -are apparently unable to rename modules at load time (the "-o bond1" -part). Attempts to pass that option to modprobe will produce an -"Operation not permitted" error. This has been reported on some -Fedora Core kernels, and has been seen on RHEL 4 as well. On kernels -exhibiting this problem, it will be impossible to configure multiple -bonds with differing parameters. + Initscripts packages that are included with Fedora 7 and Red Hat +Enterprise Linux 5 support multiple bonding interfaces by simply +specifying the appropriate BONDING_OPTS= in ifcfg-bondX where X is the +number of the bond. This support requires sysfs support in the kernel, +and a bonding driver of version 3.0.0 or later. Other configurations may +not support this method for specifying multiple bonding interfaces; for +those instances, see the "Configuring Multiple Bonds Manually" section, +below. 3.3 Configuring Bonding Manually with Ifenslave ----------------------------------------------- @@ -977,15 +1001,58 @@ initialization scripts lack support for configuring multiple bonds. options, you may wish to use the "max_bonds" module parameter, documented above. - To create multiple bonding devices with differing options, it -is necessary to use bonding parameters exported by sysfs, documented -in the section below. + To create multiple bonding devices with differing options, it is +preferrable to use bonding parameters exported by sysfs, documented in the +section below. + + For versions of bonding without sysfs support, the only means to +provide multiple instances of bonding with differing options is to load +the bonding driver multiple times. Note that current versions of the +sysconfig network initialization scripts handle this automatically; if +your distro uses these scripts, no special action is needed. See the +section Configuring Bonding Devices, above, if you're not sure about your +network initialization scripts. + + To load multiple instances of the module, it is necessary to +specify a different name for each instance (the module loading system +requires that every loaded module, even multiple instances of the same +module, have a unique name). This is accomplished by supplying multiple +sets of bonding options in /etc/modprobe.conf, for example: + +alias bond0 bonding +options bond0 -o bond0 mode=balance-rr miimon=100 + +alias bond1 bonding +options bond1 -o bond1 mode=balance-alb miimon=50 + + will load the bonding module two times. The first instance is +named "bond0" and creates the bond0 device in balance-rr mode with an +miimon of 100. The second instance is named "bond1" and creates the +bond1 device in balance-alb mode with an miimon of 50. + + In some circumstances (typically with older distributions), +the above does not work, and the second bonding instance never sees +its options. In that case, the second options line can be substituted +as follows: + +install bond1 /sbin/modprobe --ignore-install bonding -o bond1 \ + mode=balance-alb miimon=50 + This may be repeated any number of times, specifying a new and +unique name in place of bond1 for each subsequent instance. + + It has been observed that some Red Hat supplied kernels are unable +to rename modules at load time (the "-o bond1" part). Attempts to pass +that option to modprobe will produce an "Operation not permitted" error. +This has been reported on some Fedora Core kernels, and has been seen on +RHEL 4 as well. On kernels exhibiting this problem, it will be impossible +to configure multiple bonds with differing parameters (as they are older +kernels, and also lack sysfs support). 3.4 Configuring Bonding Manually via Sysfs ------------------------------------------ - Starting with version 3.0, Channel Bonding may be configured + Starting with version 3.0.0, Channel Bonding may be configured via the sysfs interface. This interface allows dynamic configuration of all bonds in the system without unloading the module. It also allows for adding and removing bonds at runtime. Ifenslave is no @@ -1030,9 +1097,6 @@ To enslave interface eth0 to bond bond0: To free slave eth0 from bond bond0: # echo -eth0 > /sys/class/net/bond0/bonding/slaves - NOTE: The bond must be up before slaves can be added. All -slaves are freed when the interface is brought down. - When an interface is enslaved to a bond, symlinks between the two are created in the sysfs filesystem. In this case, you would get /sys/class/net/bond0/slave_eth0 pointing to /sys/class/net/eth0, and @@ -1622,6 +1686,15 @@ one for each switch in the network). This will insure that, regardless of which switch is active, the ARP monitor has a suitable target to query. + Note, also, that of late many switches now support a functionality +generally referred to as "trunk failover." This is a feature of the +switch that causes the link state of a particular switch port to be set +down (or up) when the state of another switch port goes down (or up). +It's purpose is to propogate link failures from logically "exterior" ports +to the logically "interior" ports that bonding is able to monitor via +miimon. Availability and configuration for trunk failover varies by +switch, but this can be a viable alternative to the ARP monitor when using +suitable switches. 12. Configuring Bonding for Maximum Throughput ============================================== @@ -1709,7 +1782,7 @@ balance-rr: This mode is the only mode that will permit a single interfaces. It is therefore the only mode that will allow a single TCP/IP stream to utilize more than one interface's worth of throughput. This comes at a cost, however: the - striping often results in peer systems receiving packets out + striping generally results in peer systems receiving packets out of order, causing TCP/IP's congestion control system to kick in, often by retransmitting segments. @@ -1721,22 +1794,20 @@ balance-rr: This mode is the only mode that will permit a single interface's worth of throughput, even after adjusting tcp_reordering. - Note that this out of order delivery occurs when both the - sending and receiving systems are utilizing a multiple - interface bond. Consider a configuration in which a - balance-rr bond feeds into a single higher capacity network - channel (e.g., multiple 100Mb/sec ethernets feeding a single - gigabit ethernet via an etherchannel capable switch). In this - configuration, traffic sent from the multiple 100Mb devices to - a destination connected to the gigabit device will not see - packets out of order. However, traffic sent from the gigabit - device to the multiple 100Mb devices may or may not see - traffic out of order, depending upon the balance policy of the - switch. Many switches do not support any modes that stripe - traffic (instead choosing a port based upon IP or MAC level - addresses); for those devices, traffic flowing from the - gigabit device to the many 100Mb devices will only utilize one - interface. + Note that the fraction of packets that will be delivered out of + order is highly variable, and is unlikely to be zero. The level + of reordering depends upon a variety of factors, including the + networking interfaces, the switch, and the topology of the + configuration. Speaking in general terms, higher speed network + cards produce more reordering (due to factors such as packet + coalescing), and a "many to many" topology will reorder at a + higher rate than a "many slow to one fast" configuration. + + Many switches do not support any modes that stripe traffic + (instead choosing a port based upon IP or MAC level addresses); + for those devices, traffic for a particular connection flowing + through the switch to a balance-rr bond will not utilize greater + than one interface's worth of bandwidth. If you are utilizing protocols other than TCP/IP, UDP for example, and your application can tolerate out of order @@ -1936,6 +2007,10 @@ Failover may be delayed via the downdelay bonding module option. 13.2 Duplicated Incoming Packets -------------------------------- + NOTE: Starting with version 3.0.2, the bonding driver has logic to +suppress duplicate packets, which should largely eliminate this problem. +The following description is kept for reference. + It is not uncommon to observe a short burst of duplicated traffic when the bonding device is first used, or after it has been idle for some period of time. This is most easily observed by issuing @@ -2096,6 +2171,9 @@ The new driver was designed to be SMP safe from the start. EtherExpress PRO/100 and a 3com 3c905b, for example). For most modes, devices need not be of the same speed. + Starting with version 3.2.1, bonding also supports Infiniband +slaves in active-backup mode. + 3. How many bonding devices can I have? There is no limit. @@ -2154,11 +2232,15 @@ switches currently available support 802.3ad. 8. Where does a bonding device get its MAC address from? - If not explicitly configured (with ifconfig or ip link), the -MAC address of the bonding device is taken from its first slave -device. This MAC address is then passed to all following slaves and -remains persistent (even if the first slave is removed) until the -bonding device is brought down or reconfigured. + When using slave devices that have fixed MAC addresses, or when +the fail_over_mac option is enabled, the bonding device's MAC address is +the MAC address of the active slave. + + For other configurations, if not explicitly configured (with +ifconfig or ip link), the MAC address of the bonding device is taken from +its first slave device. This MAC address is then passed to all following +slaves and remains persistent (even if the first slave is removed) until +the bonding device is brought down or reconfigured. If you wish to change the MAC address, you can set it with ifconfig or ip link: diff --git a/MAINTAINERS b/MAINTAINERS index 9507b42..3468a8d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2023,10 +2023,12 @@ W: http://sourceforge.net/projects/e1000/ S: Supported INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT -P: Yi Zhu +P: Zhu Yi M: yi.zhu@intel.com P: James Ketrenos M: jketreno@linux.intel.com +P: Reinette Chatre +M: reinette.chatre@intel.com L: linux-wireless@vger.kernel.org L: ipw2100-devel@lists.sourceforge.net L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel @@ -2034,10 +2036,12 @@ W: http://ipw2100.sourceforge.net S: Supported INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT -P: Yi Zhu +P: Zhu Yi M: yi.zhu@intel.com P: James Ketrenos M: jketreno@linux.intel.com +P: Reinette Chatre +M: reinette.chatre@intel.com L: linux-wireless@vger.kernel.org L: ipw2100-devel@lists.sourceforge.net L: http://lists.sourceforge.net/mailman/listinfo/ipw2100-devel @@ -2047,6 +2051,8 @@ S: Supported INTEL WIRELESS WIFI LINK (iwlwifi) P: Zhu Yi M: yi.zhu@intel.com +P: Reinette Chatre +M: reinette.chatre@intel.com L: linux-wireless@vger.kernel.org L: ipw3945-devel@lists.sourceforge.net W: http://intellinuxwireless.org diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c index 08b117e..9898feb 100644 --- a/arch/ia64/hp/sim/simeth.c +++ b/arch/ia64/hp/sim/simeth.c @@ -497,11 +497,6 @@ simeth_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; - if ( dev == NULL ) { - printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq); - return IRQ_NONE; - } - /* * very simple loop because we get interrupts only when receiving */ diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile index f47fcac..e636daa 100644 --- a/arch/powerpc/platforms/pasemi/Makefile +++ b/arch/powerpc/platforms/pasemi/Makefile @@ -1,4 +1,4 @@ -obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o +obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o diff --git a/arch/powerpc/platforms/pasemi/dma_lib.c b/arch/powerpc/platforms/pasemi/dma_lib.c new file mode 100644 index 0000000..e6e4742 --- /dev/null +++ b/arch/powerpc/platforms/pasemi/dma_lib.c @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2006-2007 PA Semi, Inc + * + * Common functions for DMA access on PA Semi PWRficient + * + * 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. + * + * 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 + +#define MAX_TXCH 64 +#define MAX_RXCH 64 + +static struct pasdma_status *dma_status; + +static void __iomem *iob_regs; +static void __iomem *mac_regs[6]; +static void __iomem *dma_regs; + +static int base_hw_irq; + +static int num_txch, num_rxch; + +static struct pci_dev *dma_pdev; + +/* Bitmaps to handle allocation of channels */ + +static DECLARE_BITMAP(txch_free, MAX_TXCH); +static DECLARE_BITMAP(rxch_free, MAX_RXCH); + +/* pasemi_read_iob_reg - read IOB register + * @reg: Register to read (offset into PCI CFG space) + */ +unsigned int pasemi_read_iob_reg(unsigned int reg) +{ + return in_le32(iob_regs+reg); +} +EXPORT_SYMBOL(pasemi_read_iob_reg); + +/* pasemi_write_iob_reg - write IOB register + * @reg: Register to write to (offset into PCI CFG space) + * @val: Value to write + */ +void pasemi_write_iob_reg(unsigned int reg, unsigned int val) +{ + out_le32(iob_regs+reg, val); +} +EXPORT_SYMBOL(pasemi_write_iob_reg); + +/* pasemi_read_mac_reg - read MAC register + * @intf: MAC interface + * @reg: Register to read (offset into PCI CFG space) + */ +unsigned int pasemi_read_mac_reg(int intf, unsigned int reg) +{ + return in_le32(mac_regs[intf]+reg); +} +EXPORT_SYMBOL(pasemi_read_mac_reg); + +/* pasemi_write_mac_reg - write MAC register + * @intf: MAC interface + * @reg: Register to write to (offset into PCI CFG space) + * @val: Value to write + */ +void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val) +{ + out_le32(mac_regs[intf]+reg, val); +} +EXPORT_SYMBOL(pasemi_write_mac_reg); + +/* pasemi_read_dma_reg - read DMA register + * @reg: Register to read (offset into PCI CFG space) + */ +unsigned int pasemi_read_dma_reg(unsigned int reg) +{ + return in_le32(dma_regs+reg); +} +EXPORT_SYMBOL(pasemi_read_dma_reg); + +/* pasemi_write_dma_reg - write DMA register + * @reg: Register to write to (offset into PCI CFG space) + * @val: Value to write + */ +void pasemi_write_dma_reg(unsigned int reg, unsigned int val) +{ + out_le32(dma_regs+reg, val); +} +EXPORT_SYMBOL(pasemi_write_dma_reg); + +static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type type) +{ + int bit; + int start, limit; + + switch (type & (TXCHAN_EVT0|TXCHAN_EVT1)) { + case TXCHAN_EVT0: + start = 0; + limit = 10; + break; + case TXCHAN_EVT1: + start = 10; + limit = MAX_TXCH; + break; + default: + start = 0; + limit = MAX_TXCH; + break; + } +retry: + bit = find_next_bit(txch_free, MAX_TXCH, start); + if (bit >= limit) + return -ENOSPC; + if (!test_and_clear_bit(bit, txch_free)) + goto retry; + + return bit; +} + +static void pasemi_free_tx_chan(int chan) +{ + BUG_ON(test_bit(chan, txch_free)); + set_bit(chan, txch_free); +} + +static int pasemi_alloc_rx_chan(void) +{ + int bit; +retry: + bit = find_first_bit(rxch_free, MAX_RXCH); + if (bit >= MAX_TXCH) + return -ENOSPC; + if (!test_and_clear_bit(bit, rxch_free)) + goto retry; + + return bit; +} + +static void pasemi_free_rx_chan(int chan) +{ + BUG_ON(test_bit(chan, rxch_free)); + set_bit(chan, rxch_free); +} + +/* pasemi_dma_alloc_chan - Allocate a DMA channel + * @type: Type of channel to allocate + * @total_size: Total size of structure to allocate (to allow for more + * room behind the structure to be used by the client) + * @offset: Offset in bytes from start of the total structure to the beginning + * of struct pasemi_dmachan. Needed when struct pasemi_dmachan is + * not the first member of the client structure. + * + * pasemi_dma_alloc_chan allocates a DMA channel for use by a client. The + * type argument specifies whether it's a RX or TX channel, and in the case + * of TX channels which group it needs to belong to (if any). + * + * Returns a pointer to the total structure allocated on success, NULL + * on failure. + */ +void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type, + int total_size, int offset) +{ + void *buf; + struct pasemi_dmachan *chan; + int chno; + + BUG_ON(total_size < sizeof(struct pasemi_dmachan)); + + buf = kzalloc(total_size, GFP_KERNEL); + + if (!buf) + return NULL; + chan = buf + offset; + + chan->priv = buf; + + switch (type & (TXCHAN|RXCHAN)) { + case RXCHAN: + chno = pasemi_alloc_rx_chan(); + chan->chno = chno; + chan->irq = irq_create_mapping(NULL, + base_hw_irq + num_txch + chno); + chan->status = &dma_status->rx_sta[chno]; + break; + case TXCHAN: + chno = pasemi_alloc_tx_chan(type); + chan->chno = chno; + chan->irq = irq_create_mapping(NULL, base_hw_irq + chno); + chan->status = &dma_status->tx_sta[chno]; + break; + } + + chan->chan_type = type; + + return chan; +} +EXPORT_SYMBOL(pasemi_dma_alloc_chan); + +/* pasemi_dma_free_chan - Free a previously allocated channel + * @chan: Channel to free + * + * Frees a previously allocated channel. It will also deallocate any + * descriptor ring associated with the channel, if allocated. + */ +void pasemi_dma_free_chan(struct pasemi_dmachan *chan) +{ + if (chan->ring_virt) + pasemi_dma_free_ring(chan); + + switch (chan->chan_type & (RXCHAN|TXCHAN)) { + case RXCHAN: + pasemi_free_rx_chan(chan->chno); + break; + case TXCHAN: + pasemi_free_tx_chan(chan->chno); + break; + } + + kfree(chan->priv); +} +EXPORT_SYMBOL(pasemi_dma_free_chan); + +/* pasemi_dma_alloc_ring - Allocate descriptor ring for a channel + * @chan: Channel for which to allocate + * @ring_size: Ring size in 64-bit (8-byte) words + * + * Allocate a descriptor ring for a channel. Returns 0 on success, errno + * on failure. The passed in struct pasemi_dmachan is updated with the + * virtual and DMA addresses of the ring. + */ +int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size) +{ + BUG_ON(chan->ring_virt); + + chan->ring_size = ring_size; + + chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev, + ring_size * sizeof(u64), + &chan->ring_dma, GFP_KERNEL); + + if (!chan->ring_virt) + return -ENOMEM; + + memset(chan->ring_virt, 0, ring_size * sizeof(u64)); + + return 0; +} +EXPORT_SYMBOL(pasemi_dma_alloc_ring); + +/* pasemi_dma_free_ring - Free an allocated descriptor ring for a channel + * @chan: Channel for which to free the descriptor ring + * + * Frees a previously allocated descriptor ring for a channel. + */ +void pasemi_dma_free_ring(struct pasemi_dmachan *chan) +{ + BUG_ON(!chan->ring_virt); + + dma_free_coherent(&dma_pdev->dev, chan->ring_size * sizeof(u64), + chan->ring_virt, chan->ring_dma); + chan->ring_virt = NULL; + chan->ring_size = 0; + chan->ring_dma = 0; +} +EXPORT_SYMBOL(pasemi_dma_free_ring); + +/* pasemi_dma_start_chan - Start a DMA channel + * @chan: Channel to start + * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write + * + * Enables (starts) a DMA channel with optional additional arguments. + */ +void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta) +{ + if (chan->chan_type == RXCHAN) + pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno), + cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN); + else + pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno), + cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN); +} +EXPORT_SYMBOL(pasemi_dma_start_chan); + +/* pasemi_dma_stop_chan - Stop a DMA channel + * @chan: Channel to stop + * + * Stops (disables) a DMA channel. This is done by setting the ST bit in the + * CMDSTA register and waiting on the ACT (active) bit to clear, then + * finally disabling the whole channel. + * + * This function will only try for a short while for the channel to stop, if + * it doesn't it will return failure. + * + * Returns 1 on success, 0 on failure. + */ +#define MAX_RETRIES 5000 +int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan) +{ + int reg, retries; + u32 sta; + + if (chan->chan_type == RXCHAN) { + reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno); + pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST); + for (retries = 0; retries < MAX_RETRIES; retries++) { + sta = pasemi_read_dma_reg(reg); + if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) { + pasemi_write_dma_reg(reg, 0); + return 1; + } + cond_resched(); + } + } else { + reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno); + pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST); + for (retries = 0; retries < MAX_RETRIES; retries++) { + sta = pasemi_read_dma_reg(reg); + if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) { + pasemi_write_dma_reg(reg, 0); + return 1; + } + cond_resched(); + } + } + + return 0; +} +EXPORT_SYMBOL(pasemi_dma_stop_chan); + +/* pasemi_dma_alloc_buf - Allocate a buffer to use for DMA + * @chan: Channel to allocate for + * @size: Size of buffer in bytes + * @handle: DMA handle + * + * Allocate a buffer to be used by the DMA engine for read/write, + * similar to dma_alloc_coherent(). + * + * Returns the virtual address of the buffer, or NULL in case of failure. + */ +void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size, + dma_addr_t *handle) +{ + return dma_alloc_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL); +} +EXPORT_SYMBOL(pasemi_dma_alloc_buf); + +/* pasemi_dma_free_buf - Free a buffer used for DMA + * @chan: Channel the buffer was allocated for + * @size: Size of buffer in bytes + * @handle: DMA handle + * + * Frees a previously allocated buffer. + */ +void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size, + dma_addr_t *handle) +{ + dma_free_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL); +} +EXPORT_SYMBOL(pasemi_dma_free_buf); + +static void *map_onedev(struct pci_dev *p, int index) +{ + struct device_node *dn; + void __iomem *ret; + + dn = pci_device_to_OF_node(p); + if (!dn) + goto fallback; + + ret = of_iomap(dn, index); + if (!ret) + goto fallback; + + return ret; +fallback: + /* This is hardcoded and ugly, but we have some firmware versions + * that don't provide the register space in the device tree. Luckily + * they are at well-known locations so we can just do the math here. + */ + return ioremap(0xe0000000 + (p->devfn << 12), 0x2000); +} + +/* pasemi_dma_init - Initialize the PA Semi DMA library + * + * This function initializes the DMA library. It must be called before + * any other function in the library. + * + * Returns 0 on success, errno on failure. + */ +int pasemi_dma_init(void) +{ + static spinlock_t init_lock = SPIN_LOCK_UNLOCKED; + struct pci_dev *iob_pdev; + struct pci_dev *pdev; + struct resource res; + struct device_node *dn; + int i, intf, err = 0; + u32 tmp; + + if (!machine_is(pasemi)) + return -ENODEV; + + spin_lock(&init_lock); + + /* Make sure we haven't already initialized */ + if (dma_pdev) + goto out; + + iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); + if (!iob_pdev) { + BUG(); + printk(KERN_WARNING "Can't find I/O Bridge\n"); + err = -ENODEV; + goto out; + } + iob_regs = map_onedev(iob_pdev, 0); + + dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); + if (!dma_pdev) { + BUG(); + printk(KERN_WARNING "Can't find DMA controller\n"); + err = -ENODEV; + goto out; + } + dma_regs = map_onedev(dma_pdev, 0); + base_hw_irq = virq_to_hw(dma_pdev->irq); + + pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp); + num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S; + + pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp); + num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S; + + intf = 0; + for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL); + pdev; + pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev)) + mac_regs[intf++] = map_onedev(pdev, 0); + + pci_dev_put(pdev); + + for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL); + pdev; + pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev)) + mac_regs[intf++] = map_onedev(pdev, 0); + + pci_dev_put(pdev); + + dn = pci_device_to_OF_node(iob_pdev); + if (dn) + err = of_address_to_resource(dn, 1, &res); + if (!dn || err) { + /* Fallback for old firmware */ + res.start = 0xfd800000; + res.end = res.start + 0x1000; + } + dma_status = __ioremap(res.start, res.end-res.start, 0); + pci_dev_put(iob_pdev); + + for (i = 0; i < MAX_TXCH; i++) + __set_bit(i, txch_free); + + for (i = 0; i < MAX_RXCH; i++) + __set_bit(i, rxch_free); + + printk(KERN_INFO "PA Semi PWRficient DMA library initialized " + "(%d tx, %d rx channels)\n", num_txch, num_rxch); + +out: + spin_unlock(&init_lock); + return err; +} diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index 516acab..58b344c 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -9,6 +9,7 @@ extern void __devinit pas_pci_dma_dev_setup(struct pci_dev *dev); extern void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset); extern void __init alloc_iobmap_l2(void); +extern void __init pasemi_map_registers(void); /* Power savings modes, implemented in asm */ extern void idle_spin(void); diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 615b658..06bb5b7 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -272,7 +272,7 @@ scc_enet_timeout(struct net_device *dev) * This is called from the CPM handler, not the MPC core interrupt. */ static irqreturn_t -scc_enet_interrupt(int irq, void * dev_id) +scc_enet_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; volatile struct scc_enet_private *cep; @@ -280,7 +280,7 @@ scc_enet_interrupt(int irq, void * dev_id) ushort int_events; int must_restart; - cep = (struct scc_enet_private *)dev->priv; + cep = dev->priv; /* Get the interrupt events that caused us to be here. */ diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 6f3ed6a..a3a27da 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -524,7 +524,7 @@ fcc_enet_timeout(struct net_device *dev) /* The interrupt handler. */ static irqreturn_t -fcc_enet_interrupt(int irq, void * dev_id) +fcc_enet_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; volatile struct fcc_enet_private *cep; @@ -532,7 +532,7 @@ fcc_enet_interrupt(int irq, void * dev_id) ushort int_events; int must_restart; - cep = (struct fcc_enet_private *)dev->priv; + cep = dev->priv; /* Get the interrupt events that caused us to be here. */ diff --git a/drivers/net/3c501.c b/drivers/net/3c501.c index be71868..7d25368 100644 --- a/drivers/net/3c501.c +++ b/drivers/net/3c501.c @@ -17,7 +17,7 @@ Annapolis MD 21403 Fixed (again!) the missing interrupt locking on TX/RX shifting. - Alan Cox + Alan Cox Removed calls to init_etherdev since they are no longer needed, and cleaned up modularization just a bit. The driver still allows only @@ -29,16 +29,16 @@ the board. Now getting 150K/second FTP with a 3c501 card. Still playing with a TX-TX optimisation to see if we can touch 180-200K/second as seems theoretically maximum. - 19950402 Alan Cox + 19950402 Alan Cox Cleaned up for 2.3.x because we broke SMP now. - 20000208 Alan Cox + 20000208 Alan Cox Check up pass for 2.5. Nothing significant changed - 20021009 Alan Cox + 20021009 Alan Cox Fixed zero fill corner case - 20030104 Alan Cox + 20030104 Alan Cox For the avoidance of doubt the "preferred form" of this code is one which @@ -139,8 +139,8 @@ static const char version[] = * The boilerplate probe code. */ -static int io=0x280; -static int irq=5; +static int io = 0x280; +static int irq = 5; static int mem_start; /** @@ -229,8 +229,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) * Read the station address PROM data from the special port. */ - for (i = 0; i < 6; i++) - { + for (i = 0; i < 6; i++) { outw(i, ioaddr + EL1_DATAPTR); station_addr[i] = inb(ioaddr + EL1_SAPROM); } @@ -240,28 +239,24 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) */ if (station_addr[0] == 0x02 && station_addr[1] == 0x60 - && station_addr[2] == 0x8c) - { + && station_addr[2] == 0x8c) mname = "3c501"; - } else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 - && station_addr[2] == 0xC8) - { + else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 + && station_addr[2] == 0xC8) mname = "NP943"; - } - else { + else { release_region(ioaddr, EL1_IO_EXTENT); return -ENODEV; } /* - * We auto-IRQ by shutting off the interrupt line and letting it float - * high. + * We auto-IRQ by shutting off the interrupt line and letting it + * float high. */ dev->irq = irq; - if (dev->irq < 2) - { + if (dev->irq < 2) { unsigned long irq_mask; irq_mask = probe_irq_on(); @@ -274,8 +269,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) mdelay(20); autoirq = probe_irq_off(irq_mask); - if (autoirq == 0) - { + if (autoirq == 0) { printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n", mname, ioaddr); release_region(ioaddr, EL1_IO_EXTENT); @@ -292,7 +286,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr) if (autoirq) dev->irq = autoirq; - printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr, + printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n", + dev->name, mname, dev->base_addr, autoirq ? "auto":"assigned ", dev->irq); #ifdef CONFIG_IP_MULTICAST @@ -343,7 +338,8 @@ static int el_open(struct net_device *dev) if (el_debug > 2) printk(KERN_DEBUG "%s: Doing el_open()...", dev->name); - if ((retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev))) + retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev); + if (retval) return retval; spin_lock_irqsave(&lp->lock, flags); @@ -371,8 +367,9 @@ static void el_timeout(struct net_device *dev) int ioaddr = dev->base_addr; if (el_debug) - printk (KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n", - dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS)); + printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n", + dev->name, inb(TX_STATUS), + inb(AX_STATUS), inb(RX_STATUS)); dev->stats.tx_errors++; outb(TX_NORM, TX_CMD); outb(RX_NORM, RX_CMD); @@ -425,8 +422,7 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); - do - { + do { int len = skb->len; int pad = 0; int gp_start; @@ -435,10 +431,10 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) if (len < ETH_ZLEN) pad = ETH_ZLEN - len; - gp_start = 0x800 - ( len + pad ); + gp_start = 0x800 - (len + pad); lp->tx_pkt_start = gp_start; - lp->collisions = 0; + lp->collisions = 0; dev->stats.tx_bytes += skb->len; @@ -455,37 +451,42 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) lp->txing = 1; /* - * Turn interrupts back on while we spend a pleasant afternoon - * loading bytes into the board + * Turn interrupts back on while we spend a pleasant + * afternoon loading bytes into the board */ spin_unlock_irqrestore(&lp->lock, flags); - outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */ - outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */ - outsb(DATAPORT,buf,len); /* load buffer (usual thing each byte increments the pointer) */ + /* Set rx packet area to 0. */ + outw(0x00, RX_BUF_CLR); + /* aim - packet will be loaded into buffer start */ + outw(gp_start, GP_LOW); + /* load buffer (usual thing each byte increments the pointer) */ + outsb(DATAPORT, buf, len); if (pad) { - while(pad--) /* Zero fill buffer tail */ + while (pad--) /* Zero fill buffer tail */ outb(0, DATAPORT); } - outw(gp_start, GP_LOW); /* the board reuses the same register */ + /* the board reuses the same register */ + outw(gp_start, GP_LOW); - if(lp->loading != 2) - { - outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */ - lp->loading=0; + if (lp->loading != 2) { + /* fire ... Trigger xmit. */ + outb(AX_XMIT, AX_CMD); + lp->loading = 0; dev->trans_start = jiffies; if (el_debug > 2) printk(KERN_DEBUG " queued xmit.\n"); - dev_kfree_skb (skb); + dev_kfree_skb(skb); return 0; } /* A receive upset our load, despite our best efforts */ - if(el_debug>2) - printk(KERN_DEBUG "%s: burped during tx load.\n", dev->name); + if (el_debug > 2) + printk(KERN_DEBUG "%s: burped during tx load.\n", + dev->name); spin_lock_irqsave(&lp->lock, flags); } - while(1); + while (1); } @@ -534,64 +535,59 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) */ if (el_debug > 3) - printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x", dev->name, axsr); - - if(lp->loading==1 && !lp->txing) - printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n", - dev->name); - - if (lp->txing) - { + printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x", + dev->name, axsr); - /* - * Board in transmit mode. May be loading. If we are - * loading we shouldn't have got this. - */ + if (lp->loading == 1 && !lp->txing) + printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n", + dev->name); + if (lp->txing) { + /* + * Board in transmit mode. May be loading. If we are + * loading we shouldn't have got this. + */ int txsr = inb(TX_STATUS); - if(lp->loading==1) - { - if(el_debug > 2) - { - printk(KERN_DEBUG "%s: Interrupt while loading [", dev->name); - printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW)); + if (lp->loading == 1) { + if (el_debug > 2) { + printk(KERN_DEBUG "%s: Interrupt while loading [", + dev->name); + printk(" txsr=%02x gp=%04x rp=%04x]\n", + txsr, inw(GP_LOW), inw(RX_LOW)); } - lp->loading=2; /* Force a reload */ + /* Force a reload */ + lp->loading = 2; spin_unlock(&lp->lock); goto out; } - if (el_debug > 6) - printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW)); + printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x", + txsr, inw(GP_LOW), inw(RX_LOW)); - if ((axsr & 0x80) && (txsr & TX_READY) == 0) - { + if ((axsr & 0x80) && (txsr & TX_READY) == 0) { /* - * FIXME: is there a logic to whether to keep on trying or - * reset immediately ? + * FIXME: is there a logic to whether to keep + * on trying or reset immediately ? */ - if(el_debug>1) - printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x" - " gp=%03x rp=%03x.\n", dev->name, txsr, axsr, - inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR)); + if (el_debug > 1) + printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n", + dev->name, txsr, axsr, + inw(ioaddr + EL1_DATAPTR), + inw(ioaddr + EL1_RXPTR)); lp->txing = 0; netif_wake_queue(dev); - } - else if (txsr & TX_16COLLISIONS) - { + } else if (txsr & TX_16COLLISIONS) { /* * Timed out */ if (el_debug) - printk (KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n",dev->name); + printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name); outb(AX_SYS, AX_CMD); lp->txing = 0; dev->stats.tx_aborted_errors++; netif_wake_queue(dev); - } - else if (txsr & TX_COLLISION) - { + } else if (txsr & TX_COLLISION) { /* * Retrigger xmit. */ @@ -599,7 +595,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) if (el_debug > 6) printk(KERN_DEBUG " retransmitting after a collision.\n"); /* - * Poor little chip can't reset its own start pointer + * Poor little chip can't reset its own start + * pointer */ outb(AX_SYS, AX_CMD); @@ -608,53 +605,45 @@ static irqreturn_t el_interrupt(int irq, void *dev_id) dev->stats.collisions++; spin_unlock(&lp->lock); goto out; - } - else - { + } else { /* * It worked.. we will now fall through and receive */ dev->stats.tx_packets++; if (el_debug > 6) printk(KERN_DEBUG " Tx succeeded %s\n", - (txsr & TX_RDY) ? "." : "but tx is busy!"); + (txsr & TX_RDY) ? "." : "but tx is busy!"); /* * This is safe the interrupt is atomic WRT itself. */ - lp->txing = 0; - netif_wake_queue(dev); /* In case more to transmit */ + /* In case more to transmit */ + netif_wake_queue(dev); } - } - else - { - /* - * In receive mode. - */ + } else { + /* + * In receive mode. + */ int rxsr = inb(RX_STATUS); if (el_debug > 5) - printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW)); + printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW)); /* * Just reading rx_status fixes most errors. */ if (rxsr & RX_MISSED) dev->stats.rx_missed_errors++; - else if (rxsr & RX_RUNT) - { /* Handled to avoid board lock-up. */ + else if (rxsr & RX_RUNT) { + /* Handled to avoid board lock-up. */ dev->stats.rx_length_errors++; if (el_debug > 5) printk(KERN_DEBUG " runt.\n"); - } - else if (rxsr & RX_GOOD) - { + } else if (rxsr & RX_GOOD) { /* * Receive worked. */ el_receive(dev); - } - else - { + } else { /* * Nothing? Something is broken! */ @@ -702,8 +691,7 @@ static void el_receive(struct net_device *dev) if (el_debug > 4) printk(KERN_DEBUG " el_receive %d.\n", pkt_len); - if ((pkt_len < 60) || (pkt_len > 1536)) - { + if (pkt_len < 60 || pkt_len > 1536) { if (el_debug) printk(KERN_DEBUG "%s: bogus packet, length=%d\n", dev->name, pkt_len); dev->stats.rx_over_errors++; @@ -722,26 +710,23 @@ static void el_receive(struct net_device *dev) */ outw(0x00, GP_LOW); - if (skb == NULL) - { + if (skb == NULL) { printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n", dev->name); dev->stats.rx_dropped++; return; - } - else - { - skb_reserve(skb,2); /* Force 16 byte alignment */ + } else { + skb_reserve(skb, 2); /* Force 16 byte alignment */ /* * The read increments through the bytes. The interrupt * handler will fix the pointer when it returns to * receive mode. */ - insb(DATAPORT, skb_put(skb,pkt_len), pkt_len); - skb->protocol=eth_type_trans(skb,dev); + insb(DATAPORT, skb_put(skb, pkt_len), pkt_len); + skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; dev->stats.rx_packets++; - dev->stats.rx_bytes+=pkt_len; + dev->stats.rx_bytes += pkt_len; } return; } @@ -760,7 +745,7 @@ static void el_reset(struct net_device *dev) struct net_local *lp = netdev_priv(dev); int ioaddr = dev->base_addr; - if (el_debug> 2) + if (el_debug > 2) printk(KERN_INFO "3c501 reset..."); outb(AX_RESET, AX_CMD); /* Reset the chip */ outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */ @@ -794,7 +779,8 @@ static int el1_close(struct net_device *dev) int ioaddr = dev->base_addr; if (el_debug > 2) - printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n", dev->name, ioaddr); + printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n", + dev->name, ioaddr); netif_stop_queue(dev); @@ -822,18 +808,14 @@ static void set_multicast_list(struct net_device *dev) { int ioaddr = dev->base_addr; - if(dev->flags&IFF_PROMISC) - { + if (dev->flags & IFF_PROMISC) { outb(RX_PROM, RX_CMD); inb(RX_STATUS); - } - else if (dev->mc_list || dev->flags&IFF_ALLMULTI) - { - outb(RX_MULT, RX_CMD); /* Multicast or all multicast is the same */ + } else if (dev->mc_list || dev->flags & IFF_ALLMULTI) { + /* Multicast or all multicast is the same */ + outb(RX_MULT, RX_CMD); inb(RX_STATUS); /* Clear status. */ - } - else - { + } else { outb(RX_NORM, RX_CMD); inb(RX_STATUS); } diff --git a/drivers/net/3c507.c b/drivers/net/3c507.c index 964d31a..030c147 100644 --- a/drivers/net/3c507.c +++ b/drivers/net/3c507.c @@ -747,7 +747,7 @@ static void init_82586_mem(struct net_device *dev) int boguscnt = 50; while (readw(shmem+iSCB_STATUS) == 0) if (--boguscnt == 0) { - printk("%s: i82586 initialization timed out with status %04x," + printk("%s: i82586 initialization timed out with status %04x, " "cmd %04x.\n", dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD)); break; @@ -832,10 +832,11 @@ static void el16_rx(struct net_device *dev) if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 || (pkt_len & 0xC000) != 0xC000) { - printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x" - "next %04x data-buf @%04x %04x.\n", dev->name, rx_head, - frame_status, rfd_cmd, next_rx_frame, data_buffer_addr, - pkt_len); + printk(KERN_ERR "%s: Rx frame at %#x corrupted, " + "status %04x cmd %04x next %04x " + "data-buf @%04x %04x.\n", + dev->name, rx_head, frame_status, rfd_cmd, + next_rx_frame, data_buffer_addr, pkt_len); } else if ((frame_status & 0x2000) == 0) { /* Frame Rxed, but with error. */ dev->stats.rx_errors++; @@ -851,7 +852,9 @@ static void el16_rx(struct net_device *dev) pkt_len &= 0x3fff; skb = dev_alloc_skb(pkt_len+2); if (skb == NULL) { - printk("%s: Memory squeeze, dropping packet.\n", dev->name); + printk(KERN_ERR "%s: Memory squeeze, " + "dropping packet.\n", + dev->name); dev->stats.rx_dropped++; break; } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index d9107e5..71b9af5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1594,6 +1594,18 @@ config 8139_OLD_RX_RESET experience problems, you can enable this option to restore the old RX-reset behavior. If unsure, say N. +config R6040 + tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)" + depends on NET_PCI && PCI + select CRC32 + select MII + help + This is a driver for the R6040 Fast Ethernet MACs found in the + the RDC R-321x System-on-chips. + + To compile this driver as a module, choose M here: the module + will be called r6040. This is recommended. + config SIS900 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" depends on NET_PCI && PCI @@ -2566,6 +2578,7 @@ config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" depends on PPC64 && PCI select PHYLIB + select INET_LRO help This driver supports the on-chip 1/10Gbit Ethernet controller on PA Semi's PWRficient line of chips. @@ -2591,6 +2604,15 @@ config TEHUTI help Tehuti Networks 10G Ethernet NIC +config BNX2X + tristate "Broadcom NetXtremeII 10Gb support" + depends on PCI + help + This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards. + To compile this driver as a module, choose M here: the module + will be called bnx2x. This is recommended. + + endif # NETDEV_10000 source "drivers/net/tokenring/Kconfig" diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 0e5fde4..5030b00 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -54,6 +54,7 @@ obj-$(CONFIG_TLAN) += tlan.o obj-$(CONFIG_EPIC100) += epic100.o obj-$(CONFIG_SIS190) += sis190.o obj-$(CONFIG_SIS900) += sis900.o +obj-$(CONFIG_R6040) += r6040.o obj-$(CONFIG_YELLOWFIN) += yellowfin.o obj-$(CONFIG_ACENIC) += acenic.o obj-$(CONFIG_ISERIES_VETH) += iseries_veth.o @@ -63,6 +64,7 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_FEALNX) += fealnx.o obj-$(CONFIG_TIGON3) += tg3.o obj-$(CONFIG_BNX2) += bnx2.o +obj-$(CONFIG_BNX2X) += bnx2x.o spidernet-y += spider_net.o spider_net_ethtool.o obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o obj-$(CONFIG_GELIC_NET) += ps3_gelic.o diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index e7fdd81..85f7276 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1945,13 +1945,13 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, err = pci_enable_device(pdev); if(err){ - printk(KERN_ERR "amd8111e: Cannot enable new PCI device," + printk(KERN_ERR "amd8111e: Cannot enable new PCI device, " "exiting.\n"); return err; } if(!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)){ - printk(KERN_ERR "amd8111e: Cannot find PCI base address" + printk(KERN_ERR "amd8111e: Cannot find PCI base address, " "exiting.\n"); err = -ENODEV; goto err_disable_pdev; diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index b032c1b..24d81f9 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -465,8 +465,9 @@ found: /* Snarf the interrupt vector now. */ ret = request_irq(irq, &net_interrupt, 0, DRV_NAME, dev); if (ret) { - printk (" AT1700 at %#3x is unusable due to a conflict on" - "IRQ %d.\n", ioaddr, irq); + printk(KERN_ERR "AT1700 at %#3x is unusable due to a " + "conflict on IRQ %d.\n", + ioaddr, irq); goto err_mca; } diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 3d247f3..49e9172 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -2060,11 +2060,11 @@ static int __devinit b44_get_invariants(struct b44 *bp) if (sdev->bus->bustype == SSB_BUSTYPE_SSB && instance > 1) { - addr = sdev->bus->sprom.r1.et1mac; - bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr; + addr = sdev->bus->sprom.et1mac; + bp->phy_addr = sdev->bus->sprom.et1phyaddr; } else { - addr = sdev->bus->sprom.r1.et0mac; - bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr; + addr = sdev->bus->sprom.et0mac; + bp->phy_addr = sdev->bus->sprom.et0phyaddr; } memcpy(bp->dev->dev_addr, addr, 6); diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c new file mode 100644 index 0000000..4a73c88 --- /dev/null +++ b/drivers/net/bnx2x.c @@ -0,0 +1,9064 @@ +/* bnx2x.c: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + * + * Written by: Eliezer Tamir + * Based on code from Michael Chan's bnx2 driver + * UDP CSUM errata workaround by Arik Gendelman + * Slowpath rework by Vladislav Zolotarov + * Statistics and Link managment by Yitchak Gertner + * + */ + +/* define this to make the driver freeze on error + * to allow getting debug info + * (you will need to reboot afterwords) + */ +/*#define BNX2X_STOP_ON_ERROR*/ + +#include +#include +#include +#include /* for dev_info() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NETIF_F_HW_VLAN_TX + #include + #define BCM_VLAN 1 +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bnx2x_reg.h" +#include "bnx2x_fw_defs.h" +#include "bnx2x_hsi.h" +#include "bnx2x.h" +#include "bnx2x_init.h" + +#define DRV_MODULE_VERSION "0.40.15" +#define DRV_MODULE_RELDATE "$DateTime: 2007/11/15 07:28:37 $" +#define BNX2X_BC_VER 0x040009 + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (5*HZ) + +static const char version[] __devinitdata = + "Broadcom NetXtreme II 577xx 10Gigabit Ethernet Driver " + DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("Eliezer Tamir "); +MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); +MODULE_INFO(cvs_version, "$Revision: #356 $"); + +static int use_inta; +static int poll; +static int onefunc; +static int nomcp; +static int debug; +static int use_multi; + +module_param(use_inta, int, 0); +module_param(poll, int, 0); +module_param(onefunc, int, 0); +module_param(debug, int, 0); +MODULE_PARM_DESC(use_inta, "use INT#A instead of MSI-X"); +MODULE_PARM_DESC(poll, "use polling (for debug)"); +MODULE_PARM_DESC(onefunc, "enable only first function"); +MODULE_PARM_DESC(nomcp, "ignore managment CPU (Implies onefunc)"); +MODULE_PARM_DESC(debug, "defualt debug msglevel"); + +#ifdef BNX2X_MULTI +module_param(use_multi, int, 0); +MODULE_PARM_DESC(use_multi, "use per-CPU queues"); +#endif + +enum bnx2x_board_type { + BCM57710 = 0, +}; + +/* indexed by board_t, above */ +static const struct { + char *name; +} board_info[] __devinitdata = { + { "Broadcom NetXtreme II BCM57710 XGb" } +}; + +static const struct pci_device_id bnx2x_pci_tbl[] = { + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_57710, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM57710 }, + { 0 } +}; + +MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); + +/**************************************************************************** +* General service functions +****************************************************************************/ + +/* used only at init + * locking is done by mcp + */ +static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val) +{ + pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr); + pci_write_config_dword(bp->pdev, PCICFG_GRC_DATA, val); + pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, + PCICFG_VENDOR_ID_OFFSET); +} + +#ifdef BNX2X_IND_RD +static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) +{ + u32 val; + + pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, addr); + pci_read_config_dword(bp->pdev, PCICFG_GRC_DATA, &val); + pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, + PCICFG_VENDOR_ID_OFFSET); + + return val; +} +#endif + +static 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, + DMAE_REG_GO_C8, DMAE_REG_GO_C9, DMAE_REG_GO_C10, DMAE_REG_GO_C11, + DMAE_REG_GO_C12, DMAE_REG_GO_C13, DMAE_REG_GO_C14, DMAE_REG_GO_C15 +}; + +/* copy command into DMAE command memory and set DMAE command go */ +static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, + int idx) +{ + u32 cmd_offset; + int i; + + cmd_offset = (DMAE_REG_CMD_MEM + sizeof(struct dmae_command) * idx); + for (i = 0; i < (sizeof(struct dmae_command)/4); i++) { + REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i)); + +/* DP(NETIF_MSG_DMAE, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n", + idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i)); */ + } + REG_WR(bp, dmae_reg_go_c[idx], 1); +} + +static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, + u32 dst_addr, u32 len32) +{ + struct dmae_command *dmae = &bp->dmae; + int port = bp->port; + u32 *wb_comp = bnx2x_sp(bp, wb_comp); + int timeout = 200; + + 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 + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); + 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 = BNX2X_WB_COMP_VAL; + +/* + DP(NETIF_MSG_DMAE, "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(NETIF_MSG_DMAE, "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]); +*/ + + *wb_comp = 0; + + bnx2x_post_dmae(bp, dmae, port * 8); + + udelay(5); + /* adjust timeout for emulation/FPGA */ + if (CHIP_REV_IS_SLOW(bp)) + timeout *= 100; + while (*wb_comp != BNX2X_WB_COMP_VAL) { +/* DP(NETIF_MSG_DMAE, "wb_comp 0x%08x\n", *wb_comp); */ + udelay(5); + if (!timeout) { + BNX2X_ERR("dmae timeout!\n"); + break; + } + timeout--; + } +} + +#ifdef BNX2X_DMAE_RD +static void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) +{ + struct dmae_command *dmae = &bp->dmae; + int port = bp->port; + u32 *wb_comp = bnx2x_sp(bp, wb_comp); + int timeout = 200; + + memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4); + 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 + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); + 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 = BNX2X_WB_COMP_VAL; + +/* + DP(NETIF_MSG_DMAE, "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); +*/ + + *wb_comp = 0; + + bnx2x_post_dmae(bp, dmae, port * 8); + + udelay(5); + while (*wb_comp != BNX2X_WB_COMP_VAL) { + udelay(5); + if (!timeout) { + BNX2X_ERR("dmae timeout!\n"); + break; + } + timeout--; + } +/* + DP(NETIF_MSG_DMAE, "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]); +*/ +} +#endif + +static int bnx2x_mc_assert(struct bnx2x *bp) +{ + int i, j; + int rc = 0; + char last_idx; + const char storm[] = {"XTCU"}; + const u32 intmem_base[] = { + BAR_XSTRORM_INTMEM, + BAR_TSTRORM_INTMEM, + BAR_CSTRORM_INTMEM, + BAR_USTRORM_INTMEM + }; + + /* Go through all instances of all SEMIs */ + for (i = 0; i < 4; i++) { + last_idx = REG_RD8(bp, XSTORM_ASSERT_LIST_INDEX_OFFSET + + intmem_base[i]); + BNX2X_ERR("DATA %cSTORM_ASSERT_LIST_INDEX 0x%x\n", + storm[i], last_idx); + + /* print the asserts */ + for (j = 0; j < STROM_ASSERT_ARRAY_SIZE; j++) { + u32 row0, row1, row2, row3; + + row0 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + + intmem_base[i]); + row1 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 4 + + intmem_base[i]); + row2 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 8 + + intmem_base[i]); + row3 = REG_RD(bp, XSTORM_ASSERT_LIST_OFFSET(j) + 12 + + intmem_base[i]); + + if (row0 != COMMON_ASM_INVALID_ASSERT_OPCODE) { + BNX2X_ERR("DATA %cSTORM_ASSERT_INDEX 0x%x =" + " 0x%08x 0x%08x 0x%08x 0x%08x\n", + storm[i], j, row3, row2, row1, row0); + rc++; + } else { + break; + } + } + } + return rc; +} +static void bnx2x_fw_dump(struct bnx2x *bp) +{ + u32 mark, offset; + u32 data[9]; + int word; + + mark = REG_RD(bp, MCP_REG_MCPR_SCRATCH + 0xf104); + printk(KERN_ERR PFX "begin fw dump (mark 0x%x)\n", mark); + + for (offset = mark - 0x08000000; offset <= 0xF900; offset += 0x8*4) { + for (word = 0; word < 8; word++) + data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + + offset + 4*word)); + data[8] = 0x0; + printk(KERN_ERR PFX "%s", (char *)data); + } + for (offset = 0xF108; offset <= mark - 0x08000000; offset += 0x8*4) { + for (word = 0; word < 8; word++) + data[word] = htonl(REG_RD(bp, MCP_REG_MCPR_SCRATCH + + offset + 4*word)); + data[8] = 0x0; + printk(KERN_ERR PFX "%s", (char *)data); + } + printk("\n" KERN_ERR PFX "end of fw dump\n"); +} + +static void bnx2x_panic_dump(struct bnx2x *bp) +{ + int i; + u16 j, start, end; + + BNX2X_ERR("begin crash dump -----------------\n"); + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + struct eth_tx_db_data *hw_prods = fp->hw_tx_prods; + + BNX2X_ERR("queue[%d]: tx_pkt_prod(%x) tx_pkt_cons(%x)" + " tx_bd_prod(%x) tx_bd_cons(%x) *tx_cons_sb(%x)" + " *rx_cons_sb(%x) rx_comp_prod(%x)" + " rx_comp_cons(%x) fp_c_idx(%x) fp_u_idx(%x)" + " bd data(%x,%x)\n", + i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, + fp->tx_bd_cons, *fp->tx_cons_sb, *fp->rx_cons_sb, + fp->rx_comp_prod, fp->rx_comp_cons, fp->fp_c_idx, + fp->fp_u_idx, hw_prods->packets_prod, + hw_prods->bds_prod); + + start = TX_BD(le16_to_cpu(*fp->tx_cons_sb) - 10); + end = TX_BD(le16_to_cpu(*fp->tx_cons_sb) + 245); + for (j = start; j < end; j++) { + struct sw_tx_bd *sw_bd = &fp->tx_buf_ring[j]; + + BNX2X_ERR("packet[%x]=[%p,%x]\n", j, + sw_bd->skb, sw_bd->first_bd); + } + + start = TX_BD(fp->tx_bd_cons - 10); + end = TX_BD(fp->tx_bd_cons + 254); + for (j = start; j < end; j++) { + u32 *tx_bd = (u32 *)&fp->tx_desc_ring[j]; + + BNX2X_ERR("tx_bd[%x]=[%x:%x:%x:%x]\n", + j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]); + } + + start = RX_BD(le16_to_cpu(*fp->rx_cons_sb) - 10); + end = RX_BD(le16_to_cpu(*fp->rx_cons_sb) + 503); + for (j = start; j < end; j++) { + u32 *rx_bd = (u32 *)&fp->rx_desc_ring[j]; + struct sw_rx_bd *sw_bd = &fp->rx_buf_ring[j]; + + BNX2X_ERR("rx_bd[%x]=[%x:%x] sw_bd=[%p]\n", + j, rx_bd[0], rx_bd[1], sw_bd->skb); + } + + start = RCQ_BD(fp->rx_comp_cons - 10); + end = RCQ_BD(fp->rx_comp_cons + 503); + for (j = start; j < end; j++) { + u32 *cqe = (u32 *)&fp->rx_comp_ring[j]; + + BNX2X_ERR("cqe[%x]=[%x:%x:%x:%x]\n", + j, cqe[0], cqe[1], cqe[2], cqe[3]); + } + } + + BNX2X_ERR("def_c_idx(%u) def_u_idx(%u) def_t_idx(%u)" + " def_x_idx(%u) def_att_idx(%u) attn_state(%u)" + " spq_prod_idx(%u)\n", + bp->def_c_idx, bp->def_u_idx, bp->def_t_idx, bp->def_x_idx, + bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); + + + bnx2x_mc_assert(bp); + BNX2X_ERR("end crash dump -----------------\n"); + + bp->stats_state = STATS_STATE_DISABLE; + DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); +} + +static void bnx2x_enable_int(struct bnx2x *bp) +{ + int port = bp->port; + u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; + u32 val = REG_RD(bp, addr); + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + + if (msix) { + val &= ~HC_CONFIG_0_REG_SINGLE_ISR_EN_0; + val |= (HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | + HC_CONFIG_0_REG_ATTN_BIT_EN_0); + } else { + 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); + val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; + } + + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) msi %d\n", + val, port, addr, msix); + + REG_WR(bp, addr, val); +} + +static void bnx2x_disable_int(struct bnx2x *bp) +{ + int port = bp->port; + 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); + + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", + val, port, addr); + + REG_WR(bp, addr, val); + if (REG_RD(bp, addr) != val) + BNX2X_ERR("BUG! proper val not read from IGU!\n"); +} + +static void bnx2x_disable_int_sync(struct bnx2x *bp) +{ + + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + int i; + + atomic_inc(&bp->intr_sem); + /* prevent the HW from sending interrupts*/ + bnx2x_disable_int(bp); + + /* make sure all ISRs are done */ + if (msix) { + for_each_queue(bp, i) + synchronize_irq(bp->msix_table[i].vector); + + /* one more for the Slow Path IRQ */ + synchronize_irq(bp->msix_table[i].vector); + } else + synchronize_irq(bp->pdev->irq); + + /* make sure sp_task is not running */ + cancel_work_sync(&bp->sp_task); + +} + +/* fast path code */ + +/* + * general service functions + */ + +static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 id, + u8 storm, u16 index, u8 op, u8 update) +{ + u32 igu_addr = (IGU_ADDR_INT_ACK + IGU_PORT_BASE * bp->port) * 8; + struct igu_ack_register igu_ack; + + igu_ack.status_block_index = index; + igu_ack.sb_id_and_flags = + ((id << IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT) | + (storm << IGU_ACK_REGISTER_STORM_ID_SHIFT) | + (update << IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT) | + (op << IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT)); + +/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n", + (*(u32 *)&igu_ack), BAR_IGU_INTMEM + igu_addr); */ + REG_WR(bp, BAR_IGU_INTMEM + igu_addr, (*(u32 *)&igu_ack)); +} + +static inline u16 bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) +{ + struct host_status_block *fpsb = fp->status_blk; + u16 rc = 0; + + barrier(); /* status block is written to by the chip */ + if (fp->fp_c_idx != fpsb->c_status_block.status_block_index) { + fp->fp_c_idx = fpsb->c_status_block.status_block_index; + rc |= 1; + } + if (fp->fp_u_idx != fpsb->u_status_block.status_block_index) { + fp->fp_u_idx = fpsb->u_status_block.status_block_index; + rc |= 2; + } + return rc; +} + +static inline int bnx2x_has_work(struct bnx2x_fastpath *fp) +{ + u16 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++; + + if ((rx_cons_sb != fp->rx_comp_cons) || + (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons)) + return 1; + + return 0; +} + +static u16 bnx2x_ack_int(struct bnx2x *bp) +{ + u32 igu_addr = (IGU_ADDR_SIMD_MASK + IGU_PORT_BASE * bp->port) * 8; + u32 result = REG_RD(bp, BAR_IGU_INTMEM + igu_addr); + +/* DP(NETIF_MSG_INTR, "read 0x%08x from IGU addr 0x%x\n", + result, BAR_IGU_INTMEM + igu_addr); */ + +#ifdef IGU_DEBUG +#warning IGU_DEBUG active + if (result == 0) { + BNX2X_ERR("read %x from IGU\n", result); + REG_WR(bp, TM_REG_TIMER_SOFT_RST, 0); + } +#endif + return result; +} + + +/* + * fast path service functions + */ + +/* free skb in the packet ring at pos idx + * return idx of last bd freed + */ +static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, + u16 idx) +{ + struct sw_tx_bd *tx_buf = &fp->tx_buf_ring[idx]; + struct eth_tx_bd *tx_bd; + struct sk_buff *skb = tx_buf->skb; + u16 bd_idx = tx_buf->first_bd; + int nbd; + + DP(BNX2X_MSG_OFF, "pkt_idx %d buff @(%p)->skb %p\n", + idx, tx_buf, skb); + + /* unmap first bd */ + DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); + tx_bd = &fp->tx_desc_ring[bd_idx]; + pci_unmap_single(bp->pdev, BD_UNMAP_ADDR(tx_bd), + BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE); + + nbd = le16_to_cpu(tx_bd->nbd) - 1; +#ifdef BNX2X_STOP_ON_ERROR + if (nbd > (MAX_SKB_FRAGS + 2)) { + BNX2X_ERR("bad nbd!\n"); + bnx2x_panic(); + } +#endif + + /* Skip a parse bd and the TSO split header bd + since they have no mapping */ + if (nbd) + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + + if (tx_bd->bd_flags.as_bitfield & (ETH_TX_BD_FLAGS_IP_CSUM | + ETH_TX_BD_FLAGS_TCP_CSUM | + ETH_TX_BD_FLAGS_SW_LSO)) { + if (--nbd) + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + tx_bd = &fp->tx_desc_ring[bd_idx]; + /* is this a TSO split header bd? */ + if (tx_bd->bd_flags.as_bitfield & ETH_TX_BD_FLAGS_SW_LSO) { + if (--nbd) + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + } + } + + /* now free frags */ + while (nbd > 0) { + + DP(BNX2X_MSG_OFF, "free frag bd_idx %d\n", bd_idx); + tx_bd = &fp->tx_desc_ring[bd_idx]; + pci_unmap_page(bp->pdev, BD_UNMAP_ADDR(tx_bd), + BD_UNMAP_LEN(tx_bd), PCI_DMA_TODEVICE); + if (--nbd) + bd_idx = TX_BD(NEXT_TX_IDX(bd_idx)); + } + + /* release skb */ + BUG_TRAP(skb); + dev_kfree_skb(skb); + tx_buf->first_bd = 0; + tx_buf->skb = NULL; + + return bd_idx; +} + +static inline u32 bnx2x_tx_avail(struct bnx2x_fastpath *fp) +{ + u16 used; + u32 prod; + u32 cons; + + /* Tell compiler that prod and cons can change */ + barrier(); + prod = fp->tx_bd_prod; + cons = fp->tx_bd_cons; + + used = (NUM_TX_BD - NUM_TX_RINGS + prod - cons + + (cons / TX_DESC_CNT) - (prod / TX_DESC_CNT)); + + if (prod >= cons) { + /* used = prod - cons - prod/size + cons/size */ + used -= NUM_TX_BD - NUM_TX_RINGS; + } + + BUG_TRAP(used <= fp->bp->tx_ring_size); + BUG_TRAP((fp->bp->tx_ring_size - used) <= MAX_TX_AVAIL); + + return (fp->bp->tx_ring_size - used); +} + +static void bnx2x_tx_int(struct bnx2x_fastpath *fp, int work) +{ + struct bnx2x *bp = fp->bp; + u16 hw_cons, sw_cons, bd_cons = fp->tx_bd_cons; + int done = 0; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return; +#endif + + hw_cons = le16_to_cpu(*fp->tx_cons_sb); + sw_cons = fp->tx_pkt_cons; + + while (sw_cons != hw_cons) { + u16 pkt_cons; + + 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 %d\n", + 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++; + done++; + + if (done == work) + break; + } + + fp->tx_pkt_cons = sw_cons; + fp->tx_bd_cons = bd_cons; + + /* Need to make the tx_cons update visible to start_xmit() + * before checking for netif_queue_stopped(). Without the + * memory barrier, there is a small possibility that start_xmit() + * will miss it and cause the queue to be stopped forever. + */ + smp_mb(); + + /* TBD need a thresh? */ + if (unlikely(netif_queue_stopped(bp->dev))) { + + netif_tx_lock(bp->dev); + + if (netif_queue_stopped(bp->dev) && + (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)) + netif_wake_queue(bp->dev); + + netif_tx_unlock(bp->dev); + + } +} + +static void bnx2x_sp_event(struct bnx2x_fastpath *fp, + union eth_rx_cqe *rr_cqe) +{ + struct bnx2x *bp = fp->bp; + int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data); + int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data); + + DP(NETIF_MSG_RX_STATUS, + "fp %d cid %d got ramrod #%d state is %x type is %d\n", + fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.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) state is %x\n", + command, fp->state); + } + 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; + 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; + fp->state = BNX2X_FP_STATE_HALTED; + break; + + case (RAMROD_CMD_ID_ETH_PORT_DEL | BNX2X_STATE_CLOSING_WAIT4_DELETE): + DP(NETIF_MSG_IFDOWN, "got delete ramrod\n"); + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + 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_DELETED; + break; + + case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): + DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); + break; + + default: + BNX2X_ERR("unexpected ramrod (%d) state is %x\n", + command, bp->state); + } + + mb(); /* force bnx2x_wait_ramrod to see the change */ +} + +static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, + struct bnx2x_fastpath *fp, u16 index) +{ + struct sk_buff *skb; + struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[index]; + struct eth_rx_bd *rx_bd = &fp->rx_desc_ring[index]; + dma_addr_t mapping; + + skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); + if (unlikely(skb == NULL)) + return -ENOMEM; + + mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, + PCI_DMA_FROMDEVICE); + if (unlikely(dma_mapping_error(mapping))) { + + dev_kfree_skb(skb); + return -ENOMEM; + } + + rx_buf->skb = skb; + pci_unmap_addr_set(rx_buf, mapping, mapping); + + rx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + rx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + + return 0; +} + +/* note that we are not allocating a new skb, + * we are just moving one from cons to prod + * we are not creating a new mapping, + * so there is no need to check for dma_mapping_error(). + */ +static void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, + struct sk_buff *skb, u16 cons, u16 prod) +{ + struct bnx2x *bp = fp->bp; + struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; + struct sw_rx_bd *prod_rx_buf = &fp->rx_buf_ring[prod]; + struct eth_rx_bd *cons_bd = &fp->rx_desc_ring[cons]; + struct eth_rx_bd *prod_bd = &fp->rx_desc_ring[prod]; + + pci_dma_sync_single_for_device(bp->pdev, + pci_unmap_addr(cons_rx_buf, mapping), + bp->rx_offset + RX_COPY_THRESH, + PCI_DMA_FROMDEVICE); + + prod_rx_buf->skb = cons_rx_buf->skb; + pci_unmap_addr_set(prod_rx_buf, mapping, + pci_unmap_addr(cons_rx_buf, mapping)); + *prod_bd = *cons_bd; +} + +static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) +{ + struct bnx2x *bp = fp->bp; + u16 bd_cons, bd_prod, comp_ring_cons; + u16 hw_comp_cons, sw_comp_cons, sw_comp_prod; + int rx_pkt = 0; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return 0; +#endif + + hw_comp_cons = le16_to_cpu(*fp->rx_cons_sb); + if ((hw_comp_cons & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + hw_comp_cons++; + + bd_cons = fp->rx_bd_cons; + bd_prod = fp->rx_bd_prod; + sw_comp_cons = fp->rx_comp_cons; + sw_comp_prod = fp->rx_comp_prod; + + /* Memory barrier necessary as speculative reads of the rx + * buffer can be ahead of the index in the status block + */ + rmb(); + + DP(NETIF_MSG_RX_STATUS, + "queue[%d]: hw_comp_cons %u sw_comp_cons %u\n", + fp->index, hw_comp_cons, sw_comp_cons); + + while (sw_comp_cons != hw_comp_cons) { + unsigned int len, pad; + struct sw_rx_bd *rx_buf; + struct sk_buff *skb; + union eth_rx_cqe *cqe; + + comp_ring_cons = RCQ_BD(sw_comp_cons); + bd_prod = RX_BD(bd_prod); + bd_cons = RX_BD(bd_cons); + + cqe = &fp->rx_comp_ring[comp_ring_cons]; + + DP(NETIF_MSG_RX_STATUS, "hw_comp_cons %u sw_comp_cons %u" + " comp_ring (%u) bd_ring (%u,%u)\n", + hw_comp_cons, sw_comp_cons, + comp_ring_cons, bd_prod, bd_cons); + DP(NETIF_MSG_RX_STATUS, "CQE type %x err %x status %x" + " queue %x vlan %x len %x\n", + cqe->fast_path_cqe.type, + cqe->fast_path_cqe.error_type_flags, + cqe->fast_path_cqe.status_flags, + cqe->fast_path_cqe.rss_hash_result, + cqe->fast_path_cqe.vlan_tag, cqe->fast_path_cqe.pkt_len); + + /* is this a slowpath msg? */ + if (unlikely(cqe->fast_path_cqe.type)) { + bnx2x_sp_event(fp, cqe); + goto next_cqe; + + /* this is an rx packet */ + } else { + rx_buf = &fp->rx_buf_ring[bd_cons]; + skb = rx_buf->skb; + + len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); + pad = cqe->fast_path_cqe.placement_offset; + + pci_dma_sync_single_for_device(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + pad + RX_COPY_THRESH, + PCI_DMA_FROMDEVICE); + prefetch(skb); + prefetch(((char *)(skb)) + 128); + + /* is this an error packet? */ + if (unlikely(cqe->fast_path_cqe.error_type_flags & + ETH_RX_ERROR_FALGS)) { + /* do we sometimes forward error packets anyway? */ + DP(NETIF_MSG_RX_ERR, + "ERROR flags(%u) Rx packet(%u)\n", + cqe->fast_path_cqe.error_type_flags, + sw_comp_cons); + /* TBD make sure MC counts this as a drop */ + goto reuse_rx; + } + + /* Since we don't have a jumbo ring + * copy small packets if mtu > 1500 + */ + if ((bp->dev->mtu > ETH_MAX_PACKET_SIZE) && + (len <= RX_COPY_THRESH)) { + struct sk_buff *new_skb; + + new_skb = netdev_alloc_skb(bp->dev, + len + pad); + if (new_skb == NULL) { + DP(NETIF_MSG_RX_ERR, + "ERROR packet dropped " + "because of alloc failure\n"); + /* TBD count this as a drop? */ + goto reuse_rx; + } + + /* aligned copy */ + skb_copy_from_linear_data_offset(skb, pad, + new_skb->data + pad, len); + skb_reserve(new_skb, pad); + skb_put(new_skb, len); + + bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + + skb = new_skb; + + } else if (bnx2x_alloc_rx_skb(bp, fp, bd_prod) == 0) { + pci_unmap_single(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + bp->rx_buf_use_size, + PCI_DMA_FROMDEVICE); + skb_reserve(skb, pad); + skb_put(skb, len); + + } else { + DP(NETIF_MSG_RX_ERR, + "ERROR packet dropped because " + "of alloc failure\n"); +reuse_rx: + bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + goto next_rx; + } + + skb->protocol = eth_type_trans(skb, bp->dev); + + skb->ip_summed = CHECKSUM_NONE; + if (bp->rx_csum && BNX2X_RX_SUM_OK(cqe)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + + /* TBD do we pass bad csum packets in promisc */ + } + +#ifdef BCM_VLAN + if ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) + & PARSING_FLAGS_NUMBER_OF_NESTED_VLANS) + && (bp->vlgrp != NULL)) + vlan_hwaccel_receive_skb(skb, bp->vlgrp, + le16_to_cpu(cqe->fast_path_cqe.vlan_tag)); + else +#endif + netif_receive_skb(skb); + + bp->dev->last_rx = jiffies; + +next_rx: + rx_buf->skb = NULL; + + bd_cons = NEXT_RX_IDX(bd_cons); + bd_prod = NEXT_RX_IDX(bd_prod); +next_cqe: + sw_comp_prod = NEXT_RCQ_IDX(sw_comp_prod); + sw_comp_cons = NEXT_RCQ_IDX(sw_comp_cons); + rx_pkt++; + + if ((rx_pkt == budget)) + break; + } /* while */ + + fp->rx_bd_cons = bd_cons; + fp->rx_bd_prod = bd_prod; + fp->rx_comp_cons = sw_comp_cons; + fp->rx_comp_prod = sw_comp_prod; + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_RCQ_PROD_OFFSET(bp->port, fp->index), sw_comp_prod); + + mmiowb(); /* keep prod updates ordered */ + + fp->rx_pkt += rx_pkt; + fp->rx_calls++; + + return rx_pkt; +} + +static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) +{ + struct bnx2x_fastpath *fp = fp_cookie; + struct bnx2x *bp = fp->bp; + struct net_device *dev = bp->dev; + int index = fp->index; + + DP(NETIF_MSG_INTR, "got an msix interrupt on [%d]\n", index); + bnx2x_ack_sb(bp, index, USTORM_ID, 0, IGU_INT_DISABLE, 0); + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif + + prefetch(fp->rx_cons_sb); + prefetch(fp->tx_cons_sb); + prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->status_blk->u_status_block.status_block_index); + + netif_rx_schedule(dev, &bnx2x_fp(bp, index, napi)); + return IRQ_HANDLED; +} + +static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) +{ + struct net_device *dev = dev_instance; + struct bnx2x *bp = netdev_priv(dev); + u16 status = bnx2x_ack_int(bp); + + if (unlikely(status == 0)) { + DP(NETIF_MSG_INTR, "not our interrupt!\n"); + return IRQ_NONE; + } + + DP(NETIF_MSG_INTR, "got an interrupt status is %u\n", status); + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif + + /* Return here if interrupt is shared and is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return IRQ_HANDLED; + } + + if (status & 0x2) { + struct bnx2x_fastpath *fp = &bp->fp[0]; + + prefetch(fp->rx_cons_sb); + prefetch(fp->tx_cons_sb); + prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->status_blk->u_status_block.status_block_index); + + netif_rx_schedule(dev, &bnx2x_fp(bp, 0, napi)); + + status &= ~0x2; + if (!status) + return IRQ_HANDLED; + } + + if (unlikely(status & 0x1)) { + + schedule_work(&bp->sp_task); + + status &= ~0x1; + if (!status) + return IRQ_HANDLED; + } + + DP(NETIF_MSG_INTR, "got an unknown interrupt! (status is %u)\n", + status); + + return IRQ_HANDLED; +} + +/* end of fast path */ + +/* PHY/MAC */ + +/* + * General service functions + */ + +static void bnx2x_leds_set(struct bnx2x *bp, unsigned int speed) +{ + int port = bp->port; + + NIG_WR(NIG_REG_LED_MODE_P0 + port*4, + ((bp->hw_config & SHARED_HW_CFG_LED_MODE_MASK) >> + SHARED_HW_CFG_LED_MODE_SHIFT)); + NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); + + /* Set blinking rate to ~15.9Hz */ + NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, + LED_BLINK_RATE_VAL); + NIG_WR(NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + port*4, 1); + + /* On Ax chip versions for speeds less than 10G + LED scheme is different */ + if ((CHIP_REV(bp) == CHIP_REV_Ax) && (speed < SPEED_10000)) { + NIG_WR(NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 1); + NIG_WR(NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, 0); + NIG_WR(NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + port*4, 1); + } +} + +static void bnx2x_leds_unset(struct bnx2x *bp) +{ + int port = bp->port; + + NIG_WR(NIG_REG_LED_10G_P0 + port*4, 0); + NIG_WR(NIG_REG_LED_MODE_P0 + port*4, SHARED_HW_CFG_LED_MAC1); +} + +static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) +{ + u32 val = REG_RD(bp, reg); + + val |= bits; + REG_WR(bp, reg, val); + return val; +} + +static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) +{ + u32 val = REG_RD(bp, reg); + + val &= ~bits; + REG_WR(bp, reg, val); + return val; +} + +static int bnx2x_mdio22_write(struct bnx2x *bp, u32 reg, u32 val) +{ + int rc; + u32 tmp, i; + int port = bp->port; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + +/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x val 0x%08x\n", + bp->phy_addr, reg, val); */ + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); + } + + tmp = ((bp->phy_addr << 21) | (reg << 16) | + (val & EMAC_MDIO_COMM_DATA) | + EMAC_MDIO_COMM_COMMAND_WRITE_22 | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + + for (i = 0; i < 50; i++) { + udelay(10); + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("write phy register failed\n"); + + rc = -EBUSY; + } else { + rc = 0; + } + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp |= EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + } + + return rc; +} + +static int bnx2x_mdio22_read(struct bnx2x *bp, u32 reg, u32 *ret_val) +{ + int port = bp->port; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 val, i; + int rc; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val &= ~EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); + } + + val = ((bp->phy_addr << 21) | (reg << 16) | + EMAC_MDIO_COMM_COMMAND_READ_22 | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + + for (i = 0; i < 50; i++) { + udelay(10); + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + val &= EMAC_MDIO_COMM_DATA; + break; + } + } + + if (val & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("read phy register failed\n"); + + *ret_val = 0x0; + rc = -EBUSY; + } else { + *ret_val = val; + rc = 0; + } + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val |= EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + } + +/* DP(NETIF_MSG_HW, "phy_addr 0x%x reg 0x%x ret_val 0x%08x\n", + bp->phy_addr, reg, *ret_val); */ + + return rc; +} + +static int bnx2x_mdio45_write(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +{ + int rc = 0; + u32 tmp, i; + int port = bp->port; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); + } + + /* set clause 45 mode */ + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp |= EMAC_MDIO_MODE_CLAUSE_45; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + + /* address */ + tmp = ((bp->phy_addr << 21) | (reg << 16) | addr | + EMAC_MDIO_COMM_COMMAND_ADDRESS | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + + for (i = 0; i < 50; i++) { + udelay(10); + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("write phy register failed\n"); + + rc = -EBUSY; + } else { + /* data */ + tmp = ((bp->phy_addr << 21) | (reg << 16) | val | + EMAC_MDIO_COMM_COMMAND_WRITE_45 | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, tmp); + + for (i = 0; i < 50; i++) { + udelay(10); + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + + if (tmp & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("write phy register failed\n"); + + rc = -EBUSY; + } + } + + /* unset clause 45 mode */ + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp &= ~EMAC_MDIO_MODE_CLAUSE_45; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + tmp = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + tmp |= EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, tmp); + } + + return rc; +} + +static int bnx2x_mdio45_read(struct bnx2x *bp, u32 reg, u32 addr, + u32 *ret_val) +{ + int port = bp->port; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 val, i; + int rc = 0; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val &= ~EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + udelay(40); + } + + /* set clause 45 mode */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val |= EMAC_MDIO_MODE_CLAUSE_45; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + + /* address */ + val = ((bp->phy_addr << 21) | (reg << 16) | addr | + EMAC_MDIO_COMM_COMMAND_ADDRESS | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + + for (i = 0; i < 50; i++) { + udelay(10); + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + + if (val & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("read phy register failed\n"); + + *ret_val = 0; + rc = -EBUSY; + } else { + /* data */ + val = ((bp->phy_addr << 21) | (reg << 16) | + EMAC_MDIO_COMM_COMMAND_READ_45 | + EMAC_MDIO_COMM_START_BUSY); + EMAC_WR(EMAC_REG_EMAC_MDIO_COMM, val); + + for (i = 0; i < 50; i++) { + udelay(10); + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM); + if (!(val & EMAC_MDIO_COMM_START_BUSY)) { + val &= EMAC_MDIO_COMM_DATA; + break; + } + } + + if (val & EMAC_MDIO_COMM_START_BUSY) { + BNX2X_ERR("read phy register failed\n"); + + val = 0; + rc = -EBUSY; + } + + *ret_val = val; + } + + /* unset clause 45 mode */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val &= ~EMAC_MDIO_MODE_CLAUSE_45; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); + val |= EMAC_MDIO_MODE_AUTO_POLL; + EMAC_WR(EMAC_REG_EMAC_MDIO_MODE, val); + } + + return rc; +} + +static int bnx2x_mdio45_vwrite(struct bnx2x *bp, u32 reg, u32 addr, u32 val) +{ + int i; + u32 rd_val; + + might_sleep(); + for (i = 0; i < 10; i++) { + bnx2x_mdio45_write(bp, reg, addr, val); + msleep(5); + bnx2x_mdio45_read(bp, reg, addr, &rd_val); + /* if the read value is not the same as the value we wrote, + we should write it again */ + if (rd_val == val) + return 0; + } + BNX2X_ERR("MDIO write in CL45 failed\n"); + return -EBUSY; +} + +/* + * link managment + */ + +static void bnx2x_flow_ctrl_resolve(struct bnx2x *bp, u32 gp_status) +{ + u32 ld_pause; /* local driver */ + u32 lp_pause; /* link partner */ + u32 pause_result; + + bp->flow_ctrl = 0; + + /* reolve from gp_status in case of AN complete and not sgmii */ + if ((bp->req_autoneg & AUTONEG_FLOW_CTRL) && + (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && + (!(bp->phy_flags & PHY_SGMII_FLAG)) && + (XGXS_EXT_PHY_TYPE(bp) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, + &ld_pause); + bnx2x_mdio22_read(bp, + MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, + &lp_pause); + pause_result = (ld_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5; + pause_result |= (lp_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; + DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result); + + switch (pause_result) { /* ASYM P ASYM P */ + case 0xb: /* 1 0 1 1 */ + bp->flow_ctrl = FLOW_CTRL_TX; + break; + + case 0xe: /* 1 1 1 0 */ + bp->flow_ctrl = FLOW_CTRL_RX; + break; + + case 0x5: /* 0 1 0 1 */ + case 0x7: /* 0 1 1 1 */ + case 0xd: /* 1 1 0 1 */ + case 0xf: /* 1 1 1 1 */ + bp->flow_ctrl = FLOW_CTRL_BOTH; + break; + + default: + break; + } + + } else { /* forced mode */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + if (bp->dev->mtu <= 4500) + bp->flow_ctrl = FLOW_CTRL_BOTH; + else + bp->flow_ctrl = FLOW_CTRL_TX; + break; + + case FLOW_CTRL_TX: + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + bp->flow_ctrl = bp->req_flow_ctrl; + break; + + case FLOW_CTRL_NONE: + default: + break; + } + } + DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", bp->flow_ctrl); +} + +static void bnx2x_link_settings_status(struct bnx2x *bp, u32 gp_status) +{ + bp->link_status = 0; + + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { + DP(NETIF_MSG_LINK, "link up\n"); + + bp->link_up = 1; + bp->link_status |= LINK_STATUS_LINK_UP; + + if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS) + bp->duplex = DUPLEX_FULL; + else + bp->duplex = DUPLEX_HALF; + + bnx2x_flow_ctrl_resolve(bp, gp_status); + + switch (gp_status & GP_STATUS_SPEED_MASK) { + case GP_STATUS_10M: + bp->line_speed = SPEED_10; + if (bp->duplex == DUPLEX_FULL) + bp->link_status |= LINK_10TFD; + else + bp->link_status |= LINK_10THD; + break; + + case GP_STATUS_100M: + bp->line_speed = SPEED_100; + if (bp->duplex == DUPLEX_FULL) + bp->link_status |= LINK_100TXFD; + else + bp->link_status |= LINK_100TXHD; + break; + + case GP_STATUS_1G: + case GP_STATUS_1G_KX: + bp->line_speed = SPEED_1000; + if (bp->duplex == DUPLEX_FULL) + bp->link_status |= LINK_1000TFD; + else + bp->link_status |= LINK_1000THD; + break; + + case GP_STATUS_2_5G: + bp->line_speed = SPEED_2500; + if (bp->duplex == DUPLEX_FULL) + bp->link_status |= LINK_2500TFD; + else + bp->link_status |= LINK_2500THD; + break; + + case GP_STATUS_5G: + case GP_STATUS_6G: + BNX2X_ERR("link speed unsupported gp_status 0x%x\n", + gp_status); + break; + + case GP_STATUS_10G_KX4: + case GP_STATUS_10G_HIG: + case GP_STATUS_10G_CX4: + bp->line_speed = SPEED_10000; + bp->link_status |= LINK_10GTFD; + break; + + case GP_STATUS_12G_HIG: + bp->line_speed = SPEED_12000; + bp->link_status |= LINK_12GTFD; + break; + + case GP_STATUS_12_5G: + bp->line_speed = SPEED_12500; + bp->link_status |= LINK_12_5GTFD; + break; + + case GP_STATUS_13G: + bp->line_speed = SPEED_13000; + bp->link_status |= LINK_13GTFD; + break; + + case GP_STATUS_15G: + bp->line_speed = SPEED_15000; + bp->link_status |= LINK_15GTFD; + break; + + case GP_STATUS_16G: + bp->line_speed = SPEED_16000; + bp->link_status |= LINK_16GTFD; + break; + + default: + BNX2X_ERR("link speed unsupported gp_status 0x%x\n", + gp_status); + break; + } + + bp->link_status |= LINK_STATUS_SERDES_LINK; + + if (bp->req_autoneg & AUTONEG_SPEED) { + bp->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; + + if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) + bp->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + + if (bp->autoneg & AUTONEG_PARALLEL) + bp->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; + } + + if (bp->flow_ctrl & FLOW_CTRL_TX) + bp->link_status |= LINK_STATUS_TX_FLOW_CONTROL_ENABLED; + + if (bp->flow_ctrl & FLOW_CTRL_RX) + bp->link_status |= LINK_STATUS_RX_FLOW_CONTROL_ENABLED; + + } else { /* link_down */ + DP(NETIF_MSG_LINK, "link down\n"); + + bp->link_up = 0; + + bp->line_speed = 0; + bp->duplex = DUPLEX_FULL; + bp->flow_ctrl = 0; + } + + DP(NETIF_MSG_LINK, "gp_status 0x%x link_up %d\n" + DP_LEVEL " line_speed %d duplex %d flow_ctrl 0x%x" + " link_status 0x%x\n", + gp_status, bp->link_up, bp->line_speed, bp->duplex, bp->flow_ctrl, + bp->link_status); +} + +static void bnx2x_link_int_ack(struct bnx2x *bp, int is_10g) +{ + int port = bp->port; + + /* first reset all status + * we asume only one line will be change at a time */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + (NIG_XGXS0_LINK_STATUS | + NIG_SERDES0_LINK_STATUS | + NIG_STATUS_INTERRUPT_XGXS0_LINK10G)); + if (bp->link_up) { + if (is_10g) { + /* Disable the 10G link interrupt + * by writing 1 to the status register + */ + DP(NETIF_MSG_LINK, "10G XGXS link up\n"); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + NIG_STATUS_INTERRUPT_XGXS0_LINK10G); + + } else if (bp->phy_flags & PHY_XGXS_FLAG) { + /* Disable the link interrupt + * by writing 1 to the relevant lane + * in the status register + */ + DP(NETIF_MSG_LINK, "1G XGXS link up\n"); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + ((1 << bp->ser_lane) << + NIG_XGXS0_LINK_STATUS_SIZE)); + + } else { /* SerDes */ + DP(NETIF_MSG_LINK, "SerDes 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_SERDES0_LINK_STATUS); + } + + } else { /* link_down */ + } +} + +static int bnx2x_ext_phy_is_link_up(struct bnx2x *bp) +{ + u32 ext_phy_type; + u32 ext_phy_addr; + u32 local_phy; + u32 val = 0; + u32 rx_sd, pcs_status; + + if (bp->phy_flags & PHY_XGXS_FLAG) { + local_phy = bp->phy_addr; + ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + bp->phy_addr = (u8)ext_phy_addr; + + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + DP(NETIF_MSG_LINK, "XGXS Direct\n"); + val = 1; + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + DP(NETIF_MSG_LINK, "XGXS 8705\n"); + bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val); + DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); + + bnx2x_mdio45_read(bp, EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val); + DP(NETIF_MSG_LINK, "8705 LASI status is %d\n", val); + + bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_RX_SD, &rx_sd); + val = (rx_sd & 0x1); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + DP(NETIF_MSG_LINK, "XGXS 8706\n"); + bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val); + DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); + + bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_STATUS, &val); + DP(NETIF_MSG_LINK, "8706 LASI status is %d\n", val); + + bnx2x_mdio45_read(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_RX_SD, &rx_sd); + bnx2x_mdio45_read(bp, EXT_PHY_OPT_PCS_DEVAD, + EXT_PHY_OPT_PCS_STATUS, &pcs_status); + DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x" + " pcs_status 0x%x\n", rx_sd, pcs_status); + /* link is up if both bit 0 of pmd_rx and + * bit 0 of pcs_status are set + */ + val = (rx_sd & pcs_status); + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + val = 0; + break; + } + bp->phy_addr = local_phy; + + } else { /* SerDes */ + ext_phy_type = SERDES_EXT_PHY_TYPE(bp); + switch (ext_phy_type) { + case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: + DP(NETIF_MSG_LINK, "SerDes Direct\n"); + val = 1; + break; + + case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: + DP(NETIF_MSG_LINK, "SerDes 5482\n"); + val = 1; + break; + + default: + DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", + bp->ext_phy_config); + val = 0; + break; + } + } + + return val; +} + +static void bnx2x_bmac_enable(struct bnx2x *bp, int is_lb) +{ + int port = bp->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_write[2]; + u32 val; + + DP(NETIF_MSG_LINK, "enableing 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(5); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + + /* enable access for bmac registers */ + NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + + /* XGXS control */ + wb_write[0] = 0x3c; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL, + wb_write, 2); + + /* tx MAC SA */ + wb_write[0] = ((bp->dev->dev_addr[2] << 24) | + (bp->dev->dev_addr[3] << 16) | + (bp->dev->dev_addr[4] << 8) | + bp->dev->dev_addr[5]); + wb_write[1] = ((bp->dev->dev_addr[0] << 8) | + bp->dev->dev_addr[1]); + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, + wb_write, 2); + + /* tx control */ + val = 0xc0; + if (bp->flow_ctrl & FLOW_CTRL_TX) + val |= 0x800000; + wb_write[0] = val; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_write, 2); + + /* set tx mtu */ + wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -CRC */ + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_write, 2); + + /* mac control */ + val = 0x3; + if (is_lb) { + val |= 0x4; + DP(NETIF_MSG_LINK, "enable bmac loopback\n"); + } + wb_write[0] = val; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, + wb_write, 2); + + /* rx control set to don't strip crc */ + val = 0x14; + if (bp->flow_ctrl & FLOW_CTRL_RX) + val |= 0x20; + wb_write[0] = val; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_write, 2); + + /* set rx mtu */ + wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_write, 2); + + /* set cnt max size */ + wb_write[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; /* -VLAN */ + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, + wb_write, 2); + + /* configure safc */ + wb_write[0] = 0x1000200; + wb_write[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, + wb_write, 2); + + /* fix for emulation */ + if (CHIP_REV(bp) == CHIP_REV_EMUL) { + wb_write[0] = 0xf000; + wb_write[1] = 0; + REG_WR_DMAE(bp, + bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD, + wb_write, 2); + } + + /* reset old bmac stats */ + memset(&bp->old_bmac, 0, sizeof(struct bmac_stats)); + + NIG_WR(NIG_REG_XCM0_OUT_EN + port*4, 0x0); + + /* select XGXS */ + NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); + NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); + + /* disable the NIG in/out to the emac */ + NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x0); + NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0); + NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); + + /* enable the NIG in/out to the bmac */ + NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); + + NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x1); + val = 0; + if (bp->flow_ctrl & FLOW_CTRL_TX) + val = 1; + NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); + NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x1); + + bp->phy_flags |= PHY_BMAC_FLAG; + + bp->stats_state = STATS_STATE_ENABLE; +} + +static void bnx2x_emac_enable(struct bnx2x *bp) +{ + int port = bp->port; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + u32 val; + int timeout; + + DP(NETIF_MSG_LINK, "enableing EMAC\n"); + /* reset and unreset the emac core */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); + msleep(5); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); + + /* enable emac and not bmac */ + NIG_WR(NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); + + /* for paladium */ + if (CHIP_REV(bp) == CHIP_REV_EMUL) { + /* Use lane 1 (of lanes 0-3) */ + NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); + NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); + } + /* for fpga */ + else if (CHIP_REV(bp) == CHIP_REV_FPGA) { + /* Use lane 1 (of lanes 0-3) */ + NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1); + NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); + } + /* ASIC */ + else { + if (bp->phy_flags & PHY_XGXS_FLAG) { + DP(NETIF_MSG_LINK, "XGXS\n"); + /* select the master lanes (out of 0-3) */ + NIG_WR(NIG_REG_XGXS_LANE_SEL_P0 + port*4, + bp->ser_lane); + /* select XGXS */ + NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); + + } else { /* SerDes */ + DP(NETIF_MSG_LINK, "SerDes\n"); + /* select SerDes */ + NIG_WR(NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0); + } + } + + /* enable emac */ + NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 1); + + /* init emac - use read-modify-write */ + /* self clear reset */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); + EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET)); + + timeout = 200; + while (val & EMAC_MODE_RESET) { + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); + DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); + if (!timeout) { + BNX2X_ERR("EMAC timeout!\n"); + break; + } + timeout--; + } + + /* reset tx part */ + EMAC_WR(EMAC_REG_EMAC_TX_MODE, EMAC_TX_MODE_RESET); + + timeout = 200; + while (val & EMAC_TX_MODE_RESET) { + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_TX_MODE); + DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); + if (!timeout) { + BNX2X_ERR("EMAC timeout!\n"); + break; + } + timeout--; + } + + if (CHIP_REV_IS_SLOW(bp)) { + /* config GMII mode */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); + EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII)); + + } else { /* ASIC */ + /* pause enable/disable */ + bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, + EMAC_RX_MODE_FLOW_EN); + if (bp->flow_ctrl & FLOW_CTRL_RX) + bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE, + EMAC_RX_MODE_FLOW_EN); + + bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, + EMAC_TX_MODE_EXT_PAUSE_EN); + if (bp->flow_ctrl & FLOW_CTRL_TX) + bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, + EMAC_TX_MODE_EXT_PAUSE_EN); + } + + /* KEEP_VLAN_TAG, promiscous */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); + val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; + EMAC_WR(EMAC_REG_EMAC_RX_MODE, val); + + /* identify magic packets */ + val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); + EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_MPKT)); + + /* enable emac for jumbo packets */ + EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE, + (EMAC_RX_MTU_SIZE_JUMBO_ENA | + (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); /* -VLAN */ + + /* strip CRC */ + NIG_WR(NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1); + + val = ((bp->dev->dev_addr[0] << 8) | + bp->dev->dev_addr[1]); + EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val); + + val = ((bp->dev->dev_addr[2] << 24) | + (bp->dev->dev_addr[3] << 16) | + (bp->dev->dev_addr[4] << 8) | + bp->dev->dev_addr[5]); + EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); + + /* disable the NIG in/out to the bmac */ + NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0x0); + NIG_WR(NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0); + NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0x0); + + /* enable the NIG in/out to the emac */ + NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0x1); + val = 0; + if (bp->flow_ctrl & FLOW_CTRL_TX) + val = 1; + NIG_WR(NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); + NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1); + + if (CHIP_REV(bp) == CHIP_REV_FPGA) { + /* take the BigMac out of reset */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + + /* enable access for bmac registers */ + NIG_WR(NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + } + + bp->phy_flags |= PHY_EMAC_FLAG; + + bp->stats_state = STATS_STATE_ENABLE; +} + +static void bnx2x_emac_program(struct bnx2x *bp) +{ + u16 mode = 0; + int port = bp->port; + + DP(NETIF_MSG_LINK, "setting link speed & duplex\n"); + bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, + (EMAC_MODE_25G_MODE | + EMAC_MODE_PORT_MII_10M | + EMAC_MODE_HALF_DUPLEX)); + switch (bp->line_speed) { + case SPEED_10: + mode |= EMAC_MODE_PORT_MII_10M; + break; + + case SPEED_100: + mode |= EMAC_MODE_PORT_MII; + break; + + case SPEED_1000: + mode |= EMAC_MODE_PORT_GMII; + break; + + case SPEED_2500: + mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII); + break; + + default: + /* 10G not valid for EMAC */ + BNX2X_ERR("Invalid line_speed 0x%x\n", bp->line_speed); + break; + } + + if (bp->duplex == DUPLEX_HALF) + mode |= EMAC_MODE_HALF_DUPLEX; + bnx2x_bits_en(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, + mode); + + bnx2x_leds_set(bp, bp->line_speed); +} + +static void bnx2x_set_sgmii_tx_driver(struct bnx2x *bp) +{ + u32 lp_up2; + u32 tx_driver; + + /* read precomp */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G); + bnx2x_mdio22_read(bp, MDIO_OVER_1G_LP_UP2, &lp_up2); + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_TX0); + bnx2x_mdio22_read(bp, MDIO_TX0_TX_DRIVER, &tx_driver); + + /* bits [10:7] at lp_up2, positioned at [15:12] */ + lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> + MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) << + MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT); + + if ((lp_up2 != 0) && + (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) { + /* replace tx_driver bits [15:12] */ + tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; + tx_driver |= lp_up2; + bnx2x_mdio22_write(bp, MDIO_TX0_TX_DRIVER, tx_driver); + } +} + +static void bnx2x_pbf_update(struct bnx2x *bp) +{ + int port = bp->port; + u32 init_crd, crd; + u32 count = 1000; + u32 pause = 0; + + + /* disable port */ + REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); + + /* wait for init credit */ + init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4); + crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); + DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd); + + while ((init_crd != crd) && count) { + msleep(5); + + crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); + count--; + } + crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8); + if (init_crd != crd) + BNX2X_ERR("BUG! init_crd 0x%x != crd 0x%x\n", init_crd, crd); + + if (bp->flow_ctrl & FLOW_CTRL_RX) + pause = 1; + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause); + if (pause) { + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); + /* update init credit */ + init_crd = 778; /* (800-18-4) */ + + } else { + u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)/16; + + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); + /* update init credit */ + switch (bp->line_speed) { + case SPEED_10: + case SPEED_100: + case SPEED_1000: + init_crd = thresh + 55 - 22; + break; + + case SPEED_2500: + init_crd = thresh + 138 - 22; + break; + + case SPEED_10000: + init_crd = thresh + 553 - 22; + break; + + default: + BNX2X_ERR("Invalid line_speed 0x%x\n", + bp->line_speed); + break; + } + } + REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd); + DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n", + bp->line_speed, init_crd); + + /* probe the credit changes */ + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1); + msleep(5); + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0); + + /* enable port */ + REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0); +} + +static void bnx2x_update_mng(struct bnx2x *bp) +{ + if (!nomcp) + SHMEM_WR(bp, drv_fw_mb[bp->port].link_status, + bp->link_status); +} + +static void bnx2x_link_report(struct bnx2x *bp) +{ + if (bp->link_up) { + netif_carrier_on(bp->dev); + printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name); + + printk("%d Mbps ", bp->line_speed); + + if (bp->duplex == DUPLEX_FULL) + printk("full duplex"); + else + printk("half duplex"); + + if (bp->flow_ctrl) { + if (bp->flow_ctrl & FLOW_CTRL_RX) { + printk(", receive "); + if (bp->flow_ctrl & FLOW_CTRL_TX) + printk("& transmit "); + } else { + printk(", transmit "); + } + printk("flow control ON"); + } + printk("\n"); + + } else { /* link_down */ + netif_carrier_off(bp->dev); + printk(KERN_INFO PFX "%s NIC Link is Down\n", bp->dev->name); + } +} + +static void bnx2x_link_up(struct bnx2x *bp) +{ + int port = bp->port; + + /* PBF - link up */ + bnx2x_pbf_update(bp); + + /* disable drain */ + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); + + /* update shared memory */ + bnx2x_update_mng(bp); + + /* indicate link up */ + bnx2x_link_report(bp); +} + +static void bnx2x_link_down(struct bnx2x *bp) +{ + int port = bp->port; + + /* notify stats */ + if (bp->stats_state != STATS_STATE_DISABLE) { + bp->stats_state = STATS_STATE_STOP; + DP(BNX2X_MSG_STATS, "stats_state - STOP\n"); + } + + /* indicate link down */ + bp->phy_flags &= ~(PHY_BMAC_FLAG | PHY_EMAC_FLAG); + + /* reset BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + + /* ignore drain flag interrupt */ + /* activate nig drain */ + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + + /* update shared memory */ + bnx2x_update_mng(bp); + + /* indicate link down */ + bnx2x_link_report(bp); +} + +static void bnx2x_init_mac_stats(struct bnx2x *bp); + +/* This function is called upon link interrupt */ +static void bnx2x_link_update(struct bnx2x *bp) +{ + u32 gp_status; + int port = bp->port; + int i; + int link_10g; + + DP(NETIF_MSG_LINK, "port %x, is xgxs %x, stat_mask 0x%x," + " int_mask 0x%x, saved_mask 0x%x, MI_INT %x, SERDES_LINK %x," + " 10G %x, XGXS_LINK %x\n", port, (bp->phy_flags & PHY_XGXS_FLAG), + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), bp->nig_mask, + REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68) + ); + + might_sleep(); + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_GP_STATUS); + /* avoid fast toggling */ + for (i = 0 ; i < 10 ; i++) { + msleep(10); + bnx2x_mdio22_read(bp, MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + } + + bnx2x_link_settings_status(bp, gp_status); + + /* anything 10 and over uses the bmac */ + link_10g = ((bp->line_speed >= SPEED_10000) && + (bp->line_speed <= SPEED_16000)); + + bnx2x_link_int_ack(bp, link_10g); + + /* link is up only if both local phy and external phy are up */ + if (bp->link_up && bnx2x_ext_phy_is_link_up(bp)) { + if (link_10g) { + bnx2x_bmac_enable(bp, 0); + bnx2x_leds_set(bp, SPEED_10000); + + } else { + bnx2x_emac_enable(bp); + bnx2x_emac_program(bp); + + /* AN complete? */ + if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { + if (!(bp->phy_flags & PHY_SGMII_FLAG)) + bnx2x_set_sgmii_tx_driver(bp); + } + } + bnx2x_link_up(bp); + + } else { /* link down */ + bnx2x_leds_unset(bp); + bnx2x_link_down(bp); + } + + bnx2x_init_mac_stats(bp); +} + +/* + * Init service functions + */ + +static void bnx2x_set_aer_mmd(struct bnx2x *bp) +{ + u16 offset = (bp->phy_flags & PHY_XGXS_FLAG) ? + (bp->phy_addr + bp->ser_lane) : 0; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK); + bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); +} + +static void bnx2x_set_master_ln(struct bnx2x *bp) +{ + u32 new_master_ln; + + /* set the master_ln for AN */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2); + bnx2x_mdio22_read(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + &new_master_ln); + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, + (new_master_ln | bp->ser_lane)); +} + +static void bnx2x_reset_unicore(struct bnx2x *bp) +{ + u32 mii_control; + int i; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); + /* reset the unicore */ + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET)); + + /* wait for the reset to self clear */ + for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { + udelay(5); + + /* the reset erased the previous bank value */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); + + if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { + udelay(5); + return; + } + } + + BNX2X_ERR("BUG! unicore is still in reset!\n"); +} + +static void bnx2x_set_swap_lanes(struct bnx2x *bp) +{ + /* Each two bits represents a lane number: + No swap is 0123 => 0x1b no need to enable the swap */ + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_XGXS_BLOCK2); + if (bp->rx_lane_swap != 0x1b) { + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP, + (bp->rx_lane_swap | + MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | + MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); + } else { + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); + } + + if (bp->tx_lane_swap != 0x1b) { + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP, + (bp->tx_lane_swap | + MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); + } else { + bnx2x_mdio22_write(bp, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); + } +} + +static void bnx2x_set_parallel_detection(struct bnx2x *bp) +{ + u32 control2; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL); + bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, + &control2); + + if (bp->autoneg & AUTONEG_PARALLEL) { + control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; + } else { + control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; + } + bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, + control2); + + if (bp->phy_flags & PHY_XGXS_FLAG) { + DP(NETIF_MSG_LINK, "XGXS\n"); + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_10G_PARALLEL_DETECT); + + bnx2x_mdio22_write(bp, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); + + bnx2x_mdio22_read(bp, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + &control2); + + if (bp->autoneg & AUTONEG_PARALLEL) { + control2 |= + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; + } else { + control2 &= + ~MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; + } + bnx2x_mdio22_write(bp, + MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, + control2); + } +} + +static void bnx2x_set_autoneg(struct bnx2x *bp) +{ + u32 reg_val; + + /* CL37 Autoneg */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); + if ((bp->req_autoneg & AUTONEG_SPEED) && + (bp->autoneg & AUTONEG_CL37)) { + /* CL37 Autoneg Enabled */ + reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN; + } else { + /* CL37 Autoneg Disabled */ + reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | + MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); + } + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); + + /* Enable/Disable Autodetection */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL); + bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); + reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN; + + if ((bp->req_autoneg & AUTONEG_SPEED) && + (bp->autoneg & AUTONEG_SGMII_FIBER_AUTODET)) { + reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; + } else { + reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; + } + bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); + + /* Enable TetonII and BAM autoneg */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_BAM_NEXT_PAGE); + bnx2x_mdio22_read(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, + ®_val); + if ((bp->req_autoneg & AUTONEG_SPEED) && + (bp->autoneg & AUTONEG_CL37) && (bp->autoneg & AUTONEG_BAM)) { + /* Enable BAM aneg Mode and TetonII aneg Mode */ + reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | + MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); + } else { + /* TetonII and BAM Autoneg Disabled */ + reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | + MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); + } + bnx2x_mdio22_write(bp, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, + reg_val); + + /* Enable Clause 73 Aneg */ + if ((bp->req_autoneg & AUTONEG_SPEED) && + (bp->autoneg & AUTONEG_CL73)) { + /* Enable BAM Station Manager */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_USERB0); + bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL1, + (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | + MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN | + MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN)); + + /* Merge CL73 and CL37 aneg resolution */ + bnx2x_mdio22_read(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3, + ®_val); + bnx2x_mdio22_write(bp, MDIO_CL73_USERB0_CL73_BAM_CTRL3, + (reg_val | + MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR)); + + /* Set the CL73 AN speed */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB1); + bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); + /* In the SerDes we support only the 1G. + In the XGXS we support the 10G KX4 + but we currently do not support the KR */ + if (bp->phy_flags & PHY_XGXS_FLAG) { + DP(NETIF_MSG_LINK, "XGXS\n"); + /* 10G KX4 */ + reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; + } else { + DP(NETIF_MSG_LINK, "SerDes\n"); + /* 1000M KX */ + reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; + } + bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB1_AN_ADV2, reg_val); + + /* CL73 Autoneg Enabled */ + reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; + } else { + /* CL73 Autoneg Disabled */ + reg_val = 0; + } + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0); + bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); +} + +/* program SerDes, forced speed */ +static void bnx2x_program_serdes(struct bnx2x *bp) +{ + u32 reg_val; + + /* program duplex, disable autoneg */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); + reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | + MDIO_COMBO_IEEO_MII_CONTROL_AN_EN); + if (bp->req_duplex == DUPLEX_FULL) + reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); + + /* program speed + - needed only if the speed is greater than 1G (2.5G or 10G) */ + if (bp->req_line_speed > SPEED_1000) { + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL); + bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_MISC1, ®_val); + /* clearing the speed value before setting the right speed */ + reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK; + reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M | + MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); + if (bp->req_line_speed == SPEED_10000) + reg_val |= + MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; + bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_MISC1, reg_val); + } +} + +static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x *bp) +{ + u32 val = 0; + + /* configure the 48 bits for BAM AN */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_OVER_1G); + + /* set extended capabilities */ + if (bp->advertising & ADVERTISED_2500baseT_Full) + val |= MDIO_OVER_1G_UP1_2_5G; + if (bp->advertising & ADVERTISED_10000baseT_Full) + val |= MDIO_OVER_1G_UP1_10G; + bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP1, val); + + bnx2x_mdio22_write(bp, MDIO_OVER_1G_UP3, 0); +} + +static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x *bp) +{ + u32 an_adv; + + /* for AN, we are always publishing full duplex */ + an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; + + /* set pause */ + switch (bp->pause_mode) { + case PAUSE_SYMMETRIC: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; + break; + case PAUSE_ASYMMETRIC: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + break; + case PAUSE_BOTH: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + break; + case PAUSE_NONE: + an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; + break; + } + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv); +} + +static void bnx2x_restart_autoneg(struct bnx2x *bp) +{ + if (bp->autoneg & AUTONEG_CL73) { + /* enable and restart clause 73 aneg */ + u32 an_ctrl; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0); + bnx2x_mdio22_read(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + &an_ctrl); + bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + (an_ctrl | + MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN | + MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); + + } else { + /* Enable and restart BAM/CL37 aneg */ + u32 mii_control; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | + MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | + MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN)); + } +} + +static void bnx2x_initialize_sgmii_process(struct bnx2x *bp) +{ + u32 control1; + + /* in SGMII mode, the unicore is always slave */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_SERDES_DIGITAL); + bnx2x_mdio22_read(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, + &control1); + control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT; + /* set sgmii mode (and not fiber) */ + control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | + MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); + bnx2x_mdio22_write(bp, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, + control1); + + /* if forced speed */ + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + /* set speed, disable autoneg */ + u32 mii_control; + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); + mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | + MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK | + MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); + + switch (bp->req_line_speed) { + case SPEED_100: + mii_control |= + MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100; + break; + case SPEED_1000: + mii_control |= + MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000; + break; + case SPEED_10: + /* there is nothing to set for 10M */ + break; + default: + /* invalid speed for SGMII */ + DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n", + bp->req_line_speed); + break; + } + + /* setting the full duplex */ + if (bp->req_duplex == DUPLEX_FULL) + mii_control |= + MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + mii_control); + + } else { /* AN mode */ + /* enable and restart AN */ + bnx2x_restart_autoneg(bp); + } +} + +static void bnx2x_link_int_enable(struct bnx2x *bp) +{ + int port = bp->port; + + /* setting the status to report on link up + for either XGXS or SerDes */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + (NIG_XGXS0_LINK_STATUS | + NIG_STATUS_INTERRUPT_XGXS0_LINK10G | + NIG_SERDES0_LINK_STATUS)); + + if (bp->phy_flags & PHY_XGXS_FLAG) { + /* TBD - + * in force mode (not AN) we can enable just the relevant + * interrupt + * Even in AN we might enable only one according to the AN + * speed mask + */ + bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G)); + DP(NETIF_MSG_LINK, "enable XGXS interrupt\n"); + + } else { /* SerDes */ + bnx2x_bits_en(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + NIG_MASK_SERDES0_LINK_STATUS); + DP(NETIF_MSG_LINK, "enable SerDes interrupt\n"); + } +} + +static void bnx2x_ext_phy_init(struct bnx2x *bp) +{ + int port = bp->port; + u32 ext_phy_type; + u32 ext_phy_addr; + u32 local_phy; + + if (bp->phy_flags & PHY_XGXS_FLAG) { + local_phy = bp->phy_addr; + ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + DP(NETIF_MSG_LINK, "XGXS Direct\n"); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + DP(NETIF_MSG_LINK, "XGXS 8705\n"); + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + NIG_MASK_MI_INT); + DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + + bp->phy_addr = ext_phy_type; + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_MISC_CNTL, + 0x8288); + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PHY_IDENTIFIER, + 0x7fbf); + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CMU_PLL_BYPASS, + 0x0100); + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_WIS_DEVAD, + EXT_PHY_OPT_LASI_CNTL, 0x1); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + DP(NETIF_MSG_LINK, "XGXS 8706\n"); + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + NIG_MASK_MI_INT); + DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + + bp->phy_addr = ext_phy_type; + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_PMD_DIGITAL_CNT, + 0x400); + bnx2x_mdio45_vwrite(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_LASI_CNTL, 0x1); + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + break; + } + bp->phy_addr = local_phy; + + } else { /* SerDes */ +/* ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT); +*/ + ext_phy_type = SERDES_EXT_PHY_TYPE(bp); + 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_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + NIG_MASK_MI_INT); + DP(NETIF_MSG_LINK, "enabled extenal phy int\n"); + break; + + default: + DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", + bp->ext_phy_config); + break; + } + } +} + +static void bnx2x_ext_phy_reset(struct bnx2x *bp) +{ + u32 ext_phy_type; + u32 ext_phy_addr; + u32 local_phy; + + if (bp->phy_flags & PHY_XGXS_FLAG) { + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + switch (ext_phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: + DP(NETIF_MSG_LINK, "XGXS Direct\n"); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + DP(NETIF_MSG_LINK, "XGXS 8705/6\n"); + local_phy = bp->phy_addr; + ext_phy_addr = ((bp->ext_phy_config & + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); + bp->phy_addr = (u8)ext_phy_addr; + bnx2x_mdio45_write(bp, EXT_PHY_OPT_PMA_PMD_DEVAD, + EXT_PHY_OPT_CNTL, 0xa040); + bp->phy_addr = local_phy; + break; + + default: + DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + break; + } + + } else { /* SerDes */ + ext_phy_type = SERDES_EXT_PHY_TYPE(bp); + 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"); + break; + + default: + DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", + bp->ext_phy_config); + break; + } + } +} + +static void bnx2x_link_initialize(struct bnx2x *bp) +{ + int port = bp->port; + + /* 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_ext_phy_reset(bp); + + bnx2x_set_aer_mmd(bp); + + if (bp->phy_flags & PHY_XGXS_FLAG) + bnx2x_set_master_ln(bp); + + /* reset the SerDes and wait for reset bit return low */ + bnx2x_reset_unicore(bp); + + bnx2x_set_aer_mmd(bp); + + /* setting the masterLn_def again after the reset */ + if (bp->phy_flags & PHY_XGXS_FLAG) { + bnx2x_set_master_ln(bp); + bnx2x_set_swap_lanes(bp); + } + + /* Set Parallel Detect */ + if (bp->req_autoneg & AUTONEG_SPEED) + bnx2x_set_parallel_detection(bp); + + if (bp->phy_flags & PHY_XGXS_FLAG) { + if (bp->req_line_speed && + bp->req_line_speed < SPEED_1000) { + bp->phy_flags |= PHY_SGMII_FLAG; + } else { + bp->phy_flags &= ~PHY_SGMII_FLAG; + } + } + + if (!(bp->phy_flags & PHY_SGMII_FLAG)) { + u16 bank, rx_eq; + + rx_eq = ((bp->serdes_config & + PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >> + PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT); + + DP(NETIF_MSG_LINK, "setting rx eq to %d\n", rx_eq); + for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL; + bank += (MDIO_REG_BANK_RX1 - MDIO_REG_BANK_RX0)) { + MDIO_SET_REG_BANK(bp, bank); + bnx2x_mdio22_write(bp, MDIO_RX0_RX_EQ_BOOST, + ((rx_eq & + MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) | + MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL)); + } + + /* forced speed requested? */ + if (!(bp->req_autoneg & AUTONEG_SPEED)) { + DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); + + /* disable autoneg */ + bnx2x_set_autoneg(bp); + + /* program speed and duplex */ + bnx2x_program_serdes(bp); + + } else { /* AN_mode */ + DP(NETIF_MSG_LINK, "not SGMII, AN\n"); + + /* AN enabled */ + bnx2x_set_brcm_cl37_advertisment(bp); + + /* program duplex & pause advertisment (for aneg) */ + bnx2x_set_ieee_aneg_advertisment(bp); + + /* enable autoneg */ + bnx2x_set_autoneg(bp); + + /* enalbe and restart AN */ + bnx2x_restart_autoneg(bp); + } + + } else { /* SGMII mode */ + DP(NETIF_MSG_LINK, "SGMII\n"); + + bnx2x_initialize_sgmii_process(bp); + } + + /* enable the interrupt */ + bnx2x_link_int_enable(bp); + + /* init ext phy and enable link state int */ + bnx2x_ext_phy_init(bp); +} + +static void bnx2x_phy_deassert(struct bnx2x *bp) +{ + int port = bp->port; + u32 val; + + if (bp->phy_flags & PHY_XGXS_FLAG) { + DP(NETIF_MSG_LINK, "XGXS\n"); + val = XGXS_RESET_BITS; + + } else { /* SerDes */ + DP(NETIF_MSG_LINK, "SerDes\n"); + val = SERDES_RESET_BITS; + } + + val = val << (port*16); + + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + msleep(5); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); +} + +static int bnx2x_phy_init(struct bnx2x *bp) +{ + DP(NETIF_MSG_LINK, "started\n"); + if (CHIP_REV(bp) == CHIP_REV_FPGA) { + bp->phy_flags |= PHY_EMAC_FLAG; + bp->link_up = 1; + bp->line_speed = SPEED_10000; + bp->duplex = DUPLEX_FULL; + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0); + bnx2x_emac_enable(bp); + bnx2x_link_report(bp); + return 0; + + } else if (CHIP_REV(bp) == CHIP_REV_EMUL) { + bp->phy_flags |= PHY_BMAC_FLAG; + bp->link_up = 1; + bp->line_speed = SPEED_10000; + bp->duplex = DUPLEX_FULL; + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + bp->port*4, 0); + bnx2x_bmac_enable(bp, 0); + bnx2x_link_report(bp); + return 0; + + } else { + bnx2x_phy_deassert(bp); + bnx2x_link_initialize(bp); + } + + return 0; +} + +static void bnx2x_link_reset(struct bnx2x *bp) +{ + int port = bp->port; + + /* 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_ext_phy_reset(bp); + + /* reset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, + (0x1ff << (port*16))); + + /* reset EMAC / BMAC and disable NIG interfaces */ + NIG_WR(NIG_REG_BMAC0_IN_EN + port*4, 0); + NIG_WR(NIG_REG_BMAC0_OUT_EN + port*4, 0); + + NIG_WR(NIG_REG_NIG_EMAC0_EN + port*4, 0); + NIG_WR(NIG_REG_EMAC0_IN_EN + port*4, 0); + NIG_WR(NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + + NIG_WR(NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); +} + +#ifdef BNX2X_XGXS_LB +static void bnx2x_set_xgxs_loopback(struct bnx2x *bp, int is_10g) +{ + int port = bp->port; + + if (is_10g) { + u32 md_devad; + + DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); + + /* change the uni_phy_addr in the nig */ + REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18), + &md_devad); + NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); + + /* change the aer mmd */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_AER_BLOCK); + bnx2x_mdio22_write(bp, MDIO_AER_BLOCK_AER_REG, 0x2800); + + /* config combo IEEE0 control reg for loopback */ + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_CL73_IEEEB0); + bnx2x_mdio22_write(bp, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, + 0x6041); + + /* set aer mmd back */ + bnx2x_set_aer_mmd(bp); + + /* and md_devad */ + NIG_WR(NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad); + + } else { + u32 mii_control; + + DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); + + MDIO_SET_REG_BANK(bp, MDIO_REG_BANK_COMBO_IEEE0); + bnx2x_mdio22_read(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + &mii_control); + bnx2x_mdio22_write(bp, MDIO_COMBO_IEEE0_MII_CONTROL, + (mii_control | + MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK)); + } +} +#endif + +/* end of PHY/MAC */ + +/* slow path */ + +/* + * General service functions + */ + +/* the slow path queue is odd since completions arrive on the fastpath ring */ +static int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, + u32 data_hi, u32 data_lo, int common) +{ + int port = bp->port; + + DP(NETIF_MSG_TIMER, + "spe (%x:%x) command %x hw_cid %x data (%x:%x) left %x\n", + (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); + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return -EIO; +#endif + + spin_lock(&bp->spq_lock); + + if (!bp->spq_left) { + BNX2X_ERR("BUG! SPQ ring full!\n"); + spin_unlock(&bp->spq_lock); + bnx2x_panic(); + return -EBUSY; + } + /* CID needs port number to be encoded int it */ + bp->spq_prod_bd->hdr.conn_and_cmd_data = + cpu_to_le32(((command << SPE_HDR_CMD_ID_SHIFT) | + HW_CID(bp, cid))); + bp->spq_prod_bd->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); + if (common) + bp->spq_prod_bd->hdr.type |= + cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); + + bp->spq_prod_bd->data.mac_config_addr.hi = cpu_to_le32(data_hi); + bp->spq_prod_bd->data.mac_config_addr.lo = cpu_to_le32(data_lo); + + bp->spq_left--; + + if (bp->spq_prod_bd == bp->spq_last_bd) { + bp->spq_prod_bd = bp->spq; + bp->spq_prod_idx = 0; + DP(NETIF_MSG_TIMER, "end of spq\n"); + + } else { + bp->spq_prod_bd++; + bp->spq_prod_idx++; + } + + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(port), + bp->spq_prod_idx); + + spin_unlock(&bp->spq_lock); + return 0; +} + +/* acquire split MCP access lock register */ +static int bnx2x_lock_alr(struct bnx2x *bp) +{ + int rc = 0; + u32 i, j, val; + + might_sleep(); + i = 100; + for (j = 0; j < i*10; j++) { + val = (1UL << 31); + REG_WR(bp, GRCBASE_MCP + 0x9c, val); + val = REG_RD(bp, GRCBASE_MCP + 0x9c); + if (val & (1L << 31)) + break; + + msleep(5); + } + + if (!(val & (1L << 31))) { + BNX2X_ERR("Cannot acquire nvram interface\n"); + + rc = -EBUSY; + } + + return rc; +} + +/* Release split MCP access lock register */ +static void bnx2x_unlock_alr(struct bnx2x *bp) +{ + u32 val = 0; + + REG_WR(bp, GRCBASE_MCP + 0x9c, val); +} + +static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) +{ + struct host_def_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; + } + 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; + } + return rc; +} + +/* + * slow path service functions + */ + +static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) +{ + int port = bp->port; + u32 igu_addr = (IGU_ADDR_ATTN_BITS_SET + IGU_PORT_BASE * port) * 8; + u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0; + u32 nig_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : + NIG_REG_MASK_INTERRUPT_PORT0; + + if (~bp->aeu_mask & (asserted & 0xff)) + BNX2X_ERR("IGU ERROR\n"); + if (bp->attn_state & asserted) + BNX2X_ERR("IGU ERROR\n"); + + DP(NETIF_MSG_HW, "aeu_mask %x newly asserted %x\n", + bp->aeu_mask, asserted); + bp->aeu_mask &= ~(asserted & 0xff); + DP(NETIF_MSG_HW, "after masking: aeu_mask %x\n", bp->aeu_mask); + + REG_WR(bp, aeu_addr, bp->aeu_mask); + + bp->attn_state |= asserted; + + if (asserted & ATTN_HARD_WIRED_MASK) { + if (asserted & ATTN_NIG_FOR_FUNC) { + u32 nig_status_port; + u32 nig_int_addr = port ? + NIG_REG_STATUS_INTERRUPT_PORT1 : + NIG_REG_STATUS_INTERRUPT_PORT0; + + bp->nig_mask = REG_RD(bp, nig_mask_addr); + REG_WR(bp, nig_mask_addr, 0); + + nig_status_port = REG_RD(bp, nig_int_addr); + bnx2x_link_update(bp); + + /* handle unicore attn? */ + } + if (asserted & ATTN_SW_TIMER_4_FUNC) + DP(NETIF_MSG_HW, "ATTN_SW_TIMER_4_FUNC!\n"); + + if (asserted & GPIO_2_FUNC) + DP(NETIF_MSG_HW, "GPIO_2_FUNC!\n"); + + if (asserted & GPIO_3_FUNC) + DP(NETIF_MSG_HW, "GPIO_3_FUNC!\n"); + + if (asserted & GPIO_4_FUNC) + DP(NETIF_MSG_HW, "GPIO_4_FUNC!\n"); + + if (port == 0) { + if (asserted & ATTN_GENERAL_ATTN_1) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_1!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_1, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_2) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_2!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_2, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_3) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_3!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_3, 0x0); + } + } else { + if (asserted & ATTN_GENERAL_ATTN_4) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_4!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_4, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_5) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_5!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_5, 0x0); + } + if (asserted & ATTN_GENERAL_ATTN_6) { + DP(NETIF_MSG_HW, "ATTN_GENERAL_ATTN_6!\n"); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_6, 0x0); + } + } + + } /* if hardwired */ + + DP(NETIF_MSG_HW, "about to mask 0x%08x at IGU addr 0x%x\n", + asserted, BAR_IGU_INTMEM + igu_addr); + REG_WR(bp, BAR_IGU_INTMEM + igu_addr, asserted); + + /* now set back the mask */ + if (asserted & ATTN_NIG_FOR_FUNC) + REG_WR(bp, nig_mask_addr, bp->nig_mask); +} + +static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) +{ + int port = bp->port; + int index; + struct attn_route attn; + struct attn_route group_mask; + u32 reg_addr; + u32 val; + + /* need to take HW lock because MCP or other port might also + try to handle this event */ + bnx2x_lock_alr(bp); + + attn.sig[0] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 + port*4); + 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 %llx\n", (unsigned long long)attn.sig[0]); + + 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]: %llx\n", index, + (unsigned long long)group_mask.sig[0]); + + if (attn.sig[3] & group_mask.sig[3] & + EVEREST_GEN_ATTN_IN_USE_MASK) { + + if (attn.sig[3] & BNX2X_MC_ASSERT_BITS) { + + BNX2X_ERR("MC assert!\n"); + bnx2x_panic(); + + } else if (attn.sig[3] & BNX2X_MCP_ASSERT) { + + BNX2X_ERR("MCP assert!\n"); + REG_WR(bp, + MISC_REG_AEU_GENERAL_ATTN_11, 0); + bnx2x_mc_assert(bp); + + } else { + BNX2X_ERR("UNKOWEN HW ASSERT!\n"); + } + } + + if (attn.sig[1] & group_mask.sig[1] & + BNX2X_DOORQ_ASSERT) { + + val = REG_RD(bp, DORQ_REG_DORQ_INT_STS_CLR); + BNX2X_ERR("DB hw attention 0x%x\n", val); + /* DORQ discard attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from DORQ\n"); + } + + if (attn.sig[2] & group_mask.sig[2] & + AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT) { + + val = REG_RD(bp, CFC_REG_CFC_INT_STS_CLR); + BNX2X_ERR("CFC hw attention 0x%x\n", val); + /* CFC error attention */ + if (val & 0x2) + BNX2X_ERR("FATAL error from CFC\n"); + } + + if (attn.sig[2] & group_mask.sig[2] & + AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT) { + + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_0); + BNX2X_ERR("PXP hw attention 0x%x\n", val); + /* RQ_USDMDP_FIFO_OVERFLOW */ + if (val & 0x18000) + BNX2X_ERR("FATAL error from PXP\n"); + } + + if (attn.sig[3] & group_mask.sig[3] & + EVEREST_LATCHED_ATTN_IN_USE_MASK) { + + REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, + 0x7ff); + DP(NETIF_MSG_HW, "got latched bits 0x%x\n", + attn.sig[3]); + } + + if ((attn.sig[0] & group_mask.sig[0] & + HW_INTERRUT_ASSERT_SET_0) || + (attn.sig[1] & group_mask.sig[1] & + HW_INTERRUT_ASSERT_SET_1) || + (attn.sig[2] & group_mask.sig[2] & + HW_INTERRUT_ASSERT_SET_2)) + BNX2X_ERR("FATAL HW block attention\n"); + + if ((attn.sig[0] & group_mask.sig[0] & + HW_PRTY_ASSERT_SET_0) || + (attn.sig[1] & group_mask.sig[1] & + HW_PRTY_ASSERT_SET_1) || + (attn.sig[2] & group_mask.sig[2] & + HW_PRTY_ASSERT_SET_2)) + BNX2X_ERR("FATAL HW block parity atention\n"); + } + } + + bnx2x_unlock_alr(bp); + + reg_addr = (IGU_ADDR_ATTN_BITS_CLR + IGU_PORT_BASE * port) * 8; + + val = ~deasserted; +/* DP(NETIF_MSG_INTR, "write 0x%08x to IGU addr 0x%x\n", + val, BAR_IGU_INTMEM + reg_addr); */ + REG_WR(bp, BAR_IGU_INTMEM + reg_addr, val); + + if (bp->aeu_mask & (deasserted & 0xff)) + BNX2X_ERR("IGU BUG\n"); + if (~bp->attn_state & deasserted) + BNX2X_ERR("IGU BUG\n"); + + reg_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_0; + + DP(NETIF_MSG_HW, "aeu_mask %x\n", bp->aeu_mask); + bp->aeu_mask |= (deasserted & 0xff); + + DP(NETIF_MSG_HW, "new mask %x\n", bp->aeu_mask); + REG_WR(bp, reg_addr, bp->aeu_mask); + + DP(NETIF_MSG_HW, "attn_state %x\n", bp->attn_state); + bp->attn_state &= ~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 = bp->def_status_blk->atten_status_block.attn_bits; + u32 attn_ack = 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 void bnx2x_sp_task(struct work_struct *work) +{ + struct bnx2x *bp = container_of(work, struct bnx2x, sp_task); + u16 status; + + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return; + } + + status = bnx2x_update_dsb_idx(bp); + if (status == 0) + BNX2X_ERR("spurious slowpath interrupt!\n"); + + DP(NETIF_MSG_INTR, "got a slowpath interrupt (updated %x)\n", status); + + if (status & 0x1) { + /* HW attentions */ + bnx2x_attn_int(bp); + } + + /* CStorm events: query_stats, cfc delete ramrods */ + if (status & 0x2) + bp->stat_pending = 0; + + bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, 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); +} + +static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) +{ + struct net_device *dev = dev_instance; + struct bnx2x *bp = netdev_priv(dev); + + /* Return here if interrupt is disabled */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + DP(NETIF_MSG_INTR, "called but intr_sem not 0, returning\n"); + return IRQ_HANDLED; + } + + bnx2x_ack_sb(bp, 16, XSTORM_ID, 0, IGU_INT_DISABLE, 0); + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return IRQ_HANDLED; +#endif + + schedule_work(&bp->sp_task); + + return IRQ_HANDLED; +} + +/* end of slow path */ + +/* Statistics */ + +/**************************************************************************** +* Macros +****************************************************************************/ + +#define UPDATE_STAT(s, t) \ + do { \ + estats->t += new->s - old->s; \ + old->s = new->s; \ + } while (0) + +/* sum[hi:lo] += add[hi:lo] */ +#define ADD_64(s_hi, a_hi, s_lo, a_lo) \ + do { \ + s_lo += a_lo; \ + s_hi += a_hi + (s_lo < a_lo) ? 1 : 0; \ + } while (0) + +/* difference = minuend - subtrahend */ +#define DIFF_64(d_hi, m_hi, s_hi, d_lo, m_lo, s_lo) \ + do { \ + if (m_lo < s_lo) { /* underflow */ \ + d_hi = m_hi - s_hi; \ + if (d_hi > 0) { /* we can 'loan' 1 */ \ + d_hi--; \ + d_lo = m_lo + (UINT_MAX - s_lo) + 1; \ + } else { /* m_hi <= s_hi */ \ + d_hi = 0; \ + d_lo = 0; \ + } \ + } else { /* m_lo >= s_lo */ \ + if (m_hi < s_hi) { \ + d_hi = 0; \ + d_lo = 0; \ + } else { /* m_hi >= s_hi */ \ + d_hi = m_hi - s_hi; \ + d_lo = m_lo - s_lo; \ + } \ + } \ + } while (0) + +/* minuend -= subtrahend */ +#define SUB_64(m_hi, s_hi, m_lo, s_lo) \ + do { \ + DIFF_64(m_hi, m_hi, s_hi, m_lo, m_lo, s_lo); \ + } while (0) + +#define UPDATE_STAT64(s_hi, t_hi, s_lo, t_lo) \ + do { \ + DIFF_64(diff.hi, new->s_hi, old->s_hi, \ + diff.lo, new->s_lo, old->s_lo); \ + old->s_hi = new->s_hi; \ + old->s_lo = new->s_lo; \ + ADD_64(estats->t_hi, diff.hi, \ + estats->t_lo, diff.lo); \ + } while (0) + +/* sum[hi:lo] += add */ +#define ADD_EXTEND_64(s_hi, s_lo, a) \ + do { \ + s_lo += a; \ + s_hi += (s_lo < a) ? 1 : 0; \ + } while (0) + +#define UPDATE_EXTEND_STAT(s, t_hi, t_lo) \ + do { \ + ADD_EXTEND_64(estats->t_hi, estats->t_lo, new->s); \ + } while (0) + +#define UPDATE_EXTEND_TSTAT(s, t_hi, t_lo) \ + do { \ + diff = le32_to_cpu(tclient->s) - old_tclient->s; \ + old_tclient->s = le32_to_cpu(tclient->s); \ + ADD_EXTEND_64(estats->t_hi, estats->t_lo, diff); \ + } while (0) + +/* + * General service functions + */ + +static inline long bnx2x_hilo(u32 *hiref) +{ + u32 lo = *(hiref + 1); +#if (BITS_PER_LONG == 64) + u32 hi = *hiref; + + return HILO_U64(hi, lo); +#else + return lo; +#endif +} + +/* + * Init service functions + */ + +static void bnx2x_init_mac_stats(struct bnx2x *bp) +{ + struct dmae_command *dmae; + int port = bp->port; + int loader_idx = port * 8; + u32 opcode; + u32 mac_addr; + + bp->executer_idx = 0; + if (bp->fw_mb) { + /* MCP */ + opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | + 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)); + + if (bp->link_up) + opcode |= (DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE); + + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, eth_stats) + + sizeof(u32)); + dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, eth_stats) + + sizeof(u32)); + dmae->dst_addr_lo = bp->fw_mb >> 2; + dmae->dst_addr_hi = 0; + dmae->len = (offsetof(struct bnx2x_eth_stats, mac_stx_end) - + sizeof(u32)) >> 2; + if (bp->link_up) { + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } else { + dmae->comp_addr_lo = 0; + dmae->comp_addr_hi = 0; + dmae->comp_val = 0; + } + } + + if (!bp->link_up) { + /* no need to collect statistics in link down */ + return; + } + + 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)); + + if (bp->phy_flags & PHY_BMAC_FLAG) { + + mac_addr = (port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM); + + /* BIGMAC_REGISTER_TX_STAT_GTPKT .. + BIGMAC_REGISTER_TX_STAT_GTBYT */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 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; + + /* BIGMAC_REGISTER_RX_STAT_GR64 .. + 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_gr64)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac_stats, rx_gr64)); + dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_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; + + } else if (bp->phy_flags & PHY_EMAC_FLAG) { + + mac_addr = (port ? GRCBASE_EMAC1 : GRCBASE_EMAC0); + + /* EMAC_REG_EMAC_RX_STAT_AC (EMAC_REG_EMAC_RX_STAT_AC_COUNT)*/ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_RX_STAT_AC) >> 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 = EMAC_REG_EMAC_RX_STAT_AC_COUNT; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* EMAC_REG_EMAC_RX_STAT_AC_28 */ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_RX_STAT_AC_28) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, + rx_falsecarriererrors)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, + rx_falsecarriererrors)); + dmae->len = 1; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + /* EMAC_REG_EMAC_TX_STAT_AC (EMAC_REG_EMAC_TX_STAT_AC_COUNT)*/ + dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); + dmae->opcode = opcode; + dmae->src_addr_lo = (mac_addr + + EMAC_REG_EMAC_TX_STAT_AC) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, + tx_ifhcoutoctets)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct emac_stats, + tx_ifhcoutoctets)); + dmae->len = EMAC_REG_EMAC_TX_STAT_AC_COUNT; + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + } + + /* NIG */ + 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)); + dmae->src_addr_lo = (port ? NIG_REG_STAT1_BRB_DISCARD : + NIG_REG_STAT0_BRB_DISCARD) >> 2; + dmae->src_addr_hi = 0; + dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig)); + dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig)); + dmae->len = (sizeof(struct nig_stats) - 2*sizeof(u32)) >> 2; + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, nig) + + offsetof(struct nig_stats, done)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, nig) + + offsetof(struct nig_stats, done)); + dmae->comp_val = 0xffffffff; +} + +static void bnx2x_init_stats(struct bnx2x *bp) +{ + int port = bp->port; + + bp->stats_state = STATS_STATE_DISABLE; + bp->executer_idx = 0; + + bp->old_brb_discard = REG_RD(bp, + NIG_REG_STAT0_BRB_DISCARD + port*0x38); + + memset(&bp->old_bmac, 0, sizeof(struct bmac_stats)); + memset(&bp->old_tclient, 0, sizeof(struct tstorm_per_client_stats)); + memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); + + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), 1); + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_STATS_FLAGS_OFFSET(port) + 4, 0); + + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), 1); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_STATS_FLAGS_OFFSET(port) + 4, 0); + + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), 0); + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATS_FLAGS_OFFSET(port) + 4, 0); + + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port), + U64_LO(bnx2x_sp_mapping(bp, fw_stats))); + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4, + U64_HI(bnx2x_sp_mapping(bp, fw_stats))); + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port), + U64_LO(bnx2x_sp_mapping(bp, fw_stats))); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port) + 4, + U64_HI(bnx2x_sp_mapping(bp, fw_stats))); +} + +static void bnx2x_stop_stats(struct bnx2x *bp) +{ + might_sleep(); + if (bp->stats_state != STATS_STATE_DISABLE) { + int timeout = 10; + + bp->stats_state = STATS_STATE_STOP; + DP(BNX2X_MSG_STATS, "stats_state - STOP\n"); + + while (bp->stats_state != STATS_STATE_DISABLE) { + if (!timeout) { + BNX2X_ERR("timeout wating for stats stop\n"); + break; + } + timeout--; + msleep(100); + } + } + DP(BNX2X_MSG_STATS, "stats_state - DISABLE\n"); +} + +/* + * Statistics service functions + */ + +static void bnx2x_update_bmac_stats(struct bnx2x *bp) +{ + struct regp diff; + struct regp sum; + struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac); + struct bmac_stats *old = &bp->old_bmac; + struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); + + sum.hi = 0; + sum.lo = 0; + + UPDATE_STAT64(tx_gtbyt.hi, total_bytes_transmitted_hi, + tx_gtbyt.lo, total_bytes_transmitted_lo); + + UPDATE_STAT64(tx_gtmca.hi, total_multicast_packets_transmitted_hi, + tx_gtmca.lo, total_multicast_packets_transmitted_lo); + ADD_64(sum.hi, diff.hi, sum.lo, diff.lo); + + UPDATE_STAT64(tx_gtgca.hi, total_broadcast_packets_transmitted_hi, + tx_gtgca.lo, total_broadcast_packets_transmitted_lo); + ADD_64(sum.hi, diff.hi, sum.lo, diff.lo); + + UPDATE_STAT64(tx_gtpkt.hi, total_unicast_packets_transmitted_hi, + tx_gtpkt.lo, total_unicast_packets_transmitted_lo); + SUB_64(estats->total_unicast_packets_transmitted_hi, sum.hi, + estats->total_unicast_packets_transmitted_lo, sum.lo); + + UPDATE_STAT(tx_gtxpf.lo, pause_xoff_frames_transmitted); + UPDATE_STAT(tx_gt64.lo, frames_transmitted_64_bytes); + UPDATE_STAT(tx_gt127.lo, frames_transmitted_65_127_bytes); + UPDATE_STAT(tx_gt255.lo, frames_transmitted_128_255_bytes); + UPDATE_STAT(tx_gt511.lo, frames_transmitted_256_511_bytes); + UPDATE_STAT(tx_gt1023.lo, frames_transmitted_512_1023_bytes); + UPDATE_STAT(tx_gt1518.lo, frames_transmitted_1024_1522_bytes); + UPDATE_STAT(tx_gt2047.lo, frames_transmitted_1523_9022_bytes); + UPDATE_STAT(tx_gt4095.lo, frames_transmitted_1523_9022_bytes); + UPDATE_STAT(tx_gt9216.lo, frames_transmitted_1523_9022_bytes); + UPDATE_STAT(tx_gt16383.lo, frames_transmitted_1523_9022_bytes); + + UPDATE_STAT(rx_grfcs.lo, crc_receive_errors); + UPDATE_STAT(rx_grund.lo, runt_packets_received); + UPDATE_STAT(rx_grovr.lo, stat_Dot3statsFramesTooLong); + UPDATE_STAT(rx_grxpf.lo, pause_xoff_frames_received); + UPDATE_STAT(rx_grxcf.lo, control_frames_received); + /* UPDATE_STAT(rx_grxpf.lo, control_frames_received); */ + UPDATE_STAT(rx_grfrg.lo, error_runt_packets_received); + UPDATE_STAT(rx_grjbr.lo, error_jabber_packets_received); + + UPDATE_STAT64(rx_grerb.hi, stat_IfHCInBadOctets_hi, + rx_grerb.lo, stat_IfHCInBadOctets_lo); + UPDATE_STAT64(tx_gtufl.hi, stat_IfHCOutBadOctets_hi, + tx_gtufl.lo, stat_IfHCOutBadOctets_lo); + UPDATE_STAT(tx_gterr.lo, stat_Dot3statsInternalMacTransmitErrors); + /* UPDATE_STAT(rx_grxpf.lo, stat_XoffStateEntered); */ + estats->stat_XoffStateEntered = estats->pause_xoff_frames_received; +} + +static void bnx2x_update_emac_stats(struct bnx2x *bp) +{ + struct emac_stats *new = bnx2x_sp(bp, mac_stats.emac); + struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); + + UPDATE_EXTEND_STAT(tx_ifhcoutoctets, total_bytes_transmitted_hi, + total_bytes_transmitted_lo); + UPDATE_EXTEND_STAT(tx_ifhcoutucastpkts, + total_unicast_packets_transmitted_hi, + total_unicast_packets_transmitted_lo); + UPDATE_EXTEND_STAT(tx_ifhcoutmulticastpkts, + total_multicast_packets_transmitted_hi, + total_multicast_packets_transmitted_lo); + UPDATE_EXTEND_STAT(tx_ifhcoutbroadcastpkts, + total_broadcast_packets_transmitted_hi, + total_broadcast_packets_transmitted_lo); + + estats->pause_xon_frames_transmitted += new->tx_outxonsent; + estats->pause_xoff_frames_transmitted += new->tx_outxoffsent; + estats->single_collision_transmit_frames += + new->tx_dot3statssinglecollisionframes; + estats->multiple_collision_transmit_frames += + new->tx_dot3statsmultiplecollisionframes; + estats->late_collision_frames += new->tx_dot3statslatecollisions; + estats->excessive_collision_frames += + new->tx_dot3statsexcessivecollisions; + estats->frames_transmitted_64_bytes += new->tx_etherstatspkts64octets; + estats->frames_transmitted_65_127_bytes += + new->tx_etherstatspkts65octetsto127octets; + estats->frames_transmitted_128_255_bytes += + new->tx_etherstatspkts128octetsto255octets; + estats->frames_transmitted_256_511_bytes += + new->tx_etherstatspkts256octetsto511octets; + estats->frames_transmitted_512_1023_bytes += + new->tx_etherstatspkts512octetsto1023octets; + estats->frames_transmitted_1024_1522_bytes += + new->tx_etherstatspkts1024octetsto1522octet; + estats->frames_transmitted_1523_9022_bytes += + new->tx_etherstatspktsover1522octets; + + estats->crc_receive_errors += new->rx_dot3statsfcserrors; + estats->alignment_errors += new->rx_dot3statsalignmenterrors; + estats->false_carrier_detections += new->rx_falsecarriererrors; + estats->runt_packets_received += new->rx_etherstatsundersizepkts; + estats->stat_Dot3statsFramesTooLong += new->rx_dot3statsframestoolong; + estats->pause_xon_frames_received += new->rx_xonpauseframesreceived; + estats->pause_xoff_frames_received += new->rx_xoffpauseframesreceived; + estats->control_frames_received += new->rx_maccontrolframesreceived; + estats->error_runt_packets_received += new->rx_etherstatsfragments; + estats->error_jabber_packets_received += new->rx_etherstatsjabbers; + + UPDATE_EXTEND_STAT(rx_ifhcinbadoctets, stat_IfHCInBadOctets_hi, + stat_IfHCInBadOctets_lo); + UPDATE_EXTEND_STAT(tx_ifhcoutbadoctets, stat_IfHCOutBadOctets_hi, + stat_IfHCOutBadOctets_lo); + estats->stat_Dot3statsInternalMacTransmitErrors += + new->tx_dot3statsinternalmactransmiterrors; + estats->stat_Dot3StatsCarrierSenseErrors += + new->rx_dot3statscarriersenseerrors; + estats->stat_Dot3StatsDeferredTransmissions += + new->tx_dot3statsdeferredtransmissions; + estats->stat_FlowControlDone += new->tx_flowcontroldone; + estats->stat_XoffStateEntered += new->rx_xoffstateentered; +} + +static int bnx2x_update_storm_stats(struct bnx2x *bp) +{ + struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); + struct tstorm_common_stats *tstats = &stats->tstorm_common; + struct tstorm_per_client_stats *tclient = + &tstats->client_statistics[0]; + struct tstorm_per_client_stats *old_tclient = &bp->old_tclient; + struct xstorm_common_stats *xstats = &stats->xstorm_common; + struct nig_stats *nstats = bnx2x_sp(bp, nig); + struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); + u32 diff; + + /* are DMAE stats valid? */ + if (nstats->done != 0xffffffff) { + DP(BNX2X_MSG_STATS, "stats not updated by dmae\n"); + return -1; + } + + /* are storm stats valid? */ + if (tstats->done.hi != 0xffffffff) { + DP(BNX2X_MSG_STATS, "stats not updated by tstorm\n"); + return -2; + } + if (xstats->done.hi != 0xffffffff) { + DP(BNX2X_MSG_STATS, "stats not updated by xstorm\n"); + return -3; + } + + estats->total_bytes_received_hi = + estats->valid_bytes_received_hi = + le32_to_cpu(tclient->total_rcv_bytes.hi); + estats->total_bytes_received_lo = + estats->valid_bytes_received_lo = + le32_to_cpu(tclient->total_rcv_bytes.lo); + ADD_64(estats->total_bytes_received_hi, + le32_to_cpu(tclient->rcv_error_bytes.hi), + estats->total_bytes_received_lo, + le32_to_cpu(tclient->rcv_error_bytes.lo)); + + UPDATE_EXTEND_TSTAT(rcv_unicast_pkts, + total_unicast_packets_received_hi, + total_unicast_packets_received_lo); + UPDATE_EXTEND_TSTAT(rcv_multicast_pkts, + total_multicast_packets_received_hi, + total_multicast_packets_received_lo); + UPDATE_EXTEND_TSTAT(rcv_broadcast_pkts, + total_broadcast_packets_received_hi, + total_broadcast_packets_received_lo); + + estats->frames_received_64_bytes = MAC_STX_NA; + estats->frames_received_65_127_bytes = MAC_STX_NA; + estats->frames_received_128_255_bytes = MAC_STX_NA; + estats->frames_received_256_511_bytes = MAC_STX_NA; + estats->frames_received_512_1023_bytes = MAC_STX_NA; + estats->frames_received_1024_1522_bytes = MAC_STX_NA; + estats->frames_received_1523_9022_bytes = MAC_STX_NA; + + estats->x_total_sent_bytes_hi = + le32_to_cpu(xstats->total_sent_bytes.hi); + estats->x_total_sent_bytes_lo = + le32_to_cpu(xstats->total_sent_bytes.lo); + estats->x_total_sent_pkts = le32_to_cpu(xstats->total_sent_pkts); + + estats->t_rcv_unicast_bytes_hi = + le32_to_cpu(tclient->rcv_unicast_bytes.hi); + estats->t_rcv_unicast_bytes_lo = + le32_to_cpu(tclient->rcv_unicast_bytes.lo); + estats->t_rcv_broadcast_bytes_hi = + le32_to_cpu(tclient->rcv_broadcast_bytes.hi); + estats->t_rcv_broadcast_bytes_lo = + le32_to_cpu(tclient->rcv_broadcast_bytes.lo); + estats->t_rcv_multicast_bytes_hi = + le32_to_cpu(tclient->rcv_multicast_bytes.hi); + estats->t_rcv_multicast_bytes_lo = + le32_to_cpu(tclient->rcv_multicast_bytes.lo); + estats->t_total_rcv_pkt = le32_to_cpu(tclient->total_rcv_pkts); + + estats->checksum_discard = le32_to_cpu(tclient->checksum_discard); + estats->packets_too_big_discard = + le32_to_cpu(tclient->packets_too_big_discard); + estats->jabber_packets_received = estats->packets_too_big_discard + + estats->stat_Dot3statsFramesTooLong; + estats->no_buff_discard = le32_to_cpu(tclient->no_buff_discard); + estats->ttl0_discard = le32_to_cpu(tclient->ttl0_discard); + estats->mac_discard = le32_to_cpu(tclient->mac_discard); + estats->mac_filter_discard = le32_to_cpu(tstats->mac_filter_discard); + estats->xxoverflow_discard = le32_to_cpu(tstats->xxoverflow_discard); + estats->brb_truncate_discard = + le32_to_cpu(tstats->brb_truncate_discard); + + estats->brb_discard += nstats->brb_discard - bp->old_brb_discard; + bp->old_brb_discard = nstats->brb_discard; + + estats->brb_packet = nstats->brb_packet; + estats->brb_truncate = nstats->brb_truncate; + estats->flow_ctrl_discard = nstats->flow_ctrl_discard; + estats->flow_ctrl_octets = nstats->flow_ctrl_octets; + estats->flow_ctrl_packet = nstats->flow_ctrl_packet; + estats->mng_discard = nstats->mng_discard; + estats->mng_octet_inp = nstats->mng_octet_inp; + estats->mng_octet_out = nstats->mng_octet_out; + estats->mng_packet_inp = nstats->mng_packet_inp; + estats->mng_packet_out = nstats->mng_packet_out; + estats->pbf_octets = nstats->pbf_octets; + estats->pbf_packet = nstats->pbf_packet; + estats->safc_inp = nstats->safc_inp; + + xstats->done.hi = 0; + tstats->done.hi = 0; + nstats->done = 0; + + return 0; +} + +static void bnx2x_update_net_stats(struct bnx2x *bp) +{ + struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); + struct net_device_stats *nstats = &bp->dev->stats; + + nstats->rx_packets = + bnx2x_hilo(&estats->total_unicast_packets_received_hi) + + bnx2x_hilo(&estats->total_multicast_packets_received_hi) + + bnx2x_hilo(&estats->total_broadcast_packets_received_hi); + + nstats->tx_packets = + bnx2x_hilo(&estats->total_unicast_packets_transmitted_hi) + + bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi) + + bnx2x_hilo(&estats->total_broadcast_packets_transmitted_hi); + + nstats->rx_bytes = bnx2x_hilo(&estats->total_bytes_received_hi); + + nstats->tx_bytes = + bnx2x_hilo(&estats->total_bytes_transmitted_hi); + + nstats->rx_dropped = estats->checksum_discard + + estats->mac_discard; + nstats->tx_dropped = 0; + + nstats->multicast = + bnx2x_hilo(&estats->total_multicast_packets_transmitted_hi); + + nstats->collisions = + estats->single_collision_transmit_frames + + estats->multiple_collision_transmit_frames + + estats->late_collision_frames + + estats->excessive_collision_frames; + + nstats->rx_length_errors = estats->runt_packets_received + + estats->jabber_packets_received; + nstats->rx_over_errors = estats->no_buff_discard; + nstats->rx_crc_errors = estats->crc_receive_errors; + nstats->rx_frame_errors = estats->alignment_errors; + nstats->rx_fifo_errors = estats->brb_discard + + estats->brb_truncate_discard; + nstats->rx_missed_errors = estats->xxoverflow_discard; + + nstats->rx_errors = nstats->rx_length_errors + + nstats->rx_over_errors + + nstats->rx_crc_errors + + nstats->rx_frame_errors + + nstats->rx_fifo_errors; + + nstats->tx_aborted_errors = estats->late_collision_frames + + estats->excessive_collision_frames; + nstats->tx_carrier_errors = estats->false_carrier_detections; + nstats->tx_fifo_errors = 0; + nstats->tx_heartbeat_errors = 0; + nstats->tx_window_errors = 0; + + nstats->tx_errors = nstats->tx_aborted_errors + + nstats->tx_carrier_errors; + + estats->mac_stx_start = ++estats->mac_stx_end; +} + +static void bnx2x_update_stats(struct bnx2x *bp) +{ + int i; + + if (!bnx2x_update_storm_stats(bp)) { + + if (bp->phy_flags & PHY_BMAC_FLAG) { + bnx2x_update_bmac_stats(bp); + + } else if (bp->phy_flags & PHY_EMAC_FLAG) { + bnx2x_update_emac_stats(bp); + + } else { /* unreached */ + BNX2X_ERR("no MAC active\n"); + return; + } + + bnx2x_update_net_stats(bp); + } + + if (bp->msglevel & NETIF_MSG_TIMER) { + struct bnx2x_eth_stats *estats = bnx2x_sp(bp, eth_stats); + struct net_device_stats *nstats = &bp->dev->stats; + + printk(KERN_DEBUG "%s:\n", bp->dev->name); + printk(KERN_DEBUG " tx avail (%4x) tx hc idx (%x)" + " tx pkt (%lx)\n", + bnx2x_tx_avail(bp->fp), + *bp->fp->tx_cons_sb, nstats->tx_packets); + printk(KERN_DEBUG " rx usage (%4x) rx hc idx (%x)" + " rx pkt (%lx)\n", + (u16)(*bp->fp->rx_cons_sb - bp->fp->rx_comp_cons), + *bp->fp->rx_cons_sb, nstats->rx_packets); + printk(KERN_DEBUG " %s (Xoff events %u) brb drops %u\n", + netif_queue_stopped(bp->dev)? "Xoff" : "Xon", + estats->driver_xoff, estats->brb_discard); + printk(KERN_DEBUG "tstats: checksum_discard %u " + "packets_too_big_discard %u no_buff_discard %u " + "mac_discard %u mac_filter_discard %u " + "xxovrflow_discard %u brb_truncate_discard %u " + "ttl0_discard %u\n", + estats->checksum_discard, + estats->packets_too_big_discard, + estats->no_buff_discard, estats->mac_discard, + estats->mac_filter_discard, estats->xxoverflow_discard, + estats->brb_truncate_discard, estats->ttl0_discard); + + for_each_queue(bp, i) { + printk(KERN_DEBUG "[%d]: %lu\t%lu\t%lu\n", i, + bnx2x_fp(bp, i, tx_pkt), + bnx2x_fp(bp, i, rx_pkt), + bnx2x_fp(bp, i, rx_calls)); + } + } + + if (bp->state != BNX2X_STATE_OPEN) { + DP(BNX2X_MSG_STATS, "state is %x, returning\n", bp->state); + return; + } + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return; +#endif + + /* loader */ + if (bp->executer_idx) { + struct dmae_command *dmae = &bp->dmae; + int port = bp->port; + int loader_idx = port * 8; + + 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 + (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); + 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 + + sizeof(struct dmae_command) * + (loader_idx + 1)) >> 2; + dmae->dst_addr_hi = 0; + dmae->len = sizeof(struct dmae_command) >> 2; + dmae->len--; /* !!! for A0/1 only */ + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx + 1] >> 2; + dmae->comp_addr_hi = 0; + dmae->comp_val = 1; + + bnx2x_post_dmae(bp, dmae, loader_idx); + } + + if (bp->stats_state != STATS_STATE_ENABLE) { + bp->stats_state = STATS_STATE_DISABLE; + return; + } + + if (bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, 0, 0, 0) == 0) { + /* stats ramrod has it's own slot on the spe */ + bp->spq_left++; + bp->stat_pending = 1; + } +} + +static void bnx2x_timer(unsigned long data) +{ + struct bnx2x *bp = (struct bnx2x *) data; + + if (!netif_running(bp->dev)) + return; + + if (atomic_read(&bp->intr_sem) != 0) + goto bnx2x_restart_timer; + + if (poll) { + struct bnx2x_fastpath *fp = &bp->fp[0]; + int rc; + + bnx2x_tx_int(fp, 1000); + rc = bnx2x_rx_int(fp, 1000); + } + + if (!nomcp && (bp->bc_ver >= 0x040003)) { + int port = bp->port; + u32 drv_pulse; + u32 mcp_pulse; + + ++bp->fw_drv_pulse_wr_seq; + 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, drv_fw_mb[port].drv_pulse_mb, drv_pulse); + + mcp_pulse = (SHMEM_RD(bp, drv_fw_mb[port].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) + */ + if ((drv_pulse != mcp_pulse) && + (drv_pulse != ((mcp_pulse + 1) & MCP_PULSE_SEQ_MASK))) { + /* someone lost a heartbeat... */ + BNX2X_ERR("drv_pulse (0x%x) != mcp_pulse (0x%x)\n", + drv_pulse, mcp_pulse); + } + } + + if (bp->stats_state == STATS_STATE_DISABLE) + goto bnx2x_restart_timer; + + bnx2x_update_stats(bp); + +bnx2x_restart_timer: + mod_timer(&bp->timer, jiffies + bp->current_interval); +} + +/* end of Statistics */ + +/* nic init */ + +/* + * nic init service functions + */ + +static void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, + dma_addr_t mapping, int id) +{ + int port = bp->port; + u64 section; + int index; + + /* USTORM */ + section = ((u64)mapping) + offsetof(struct host_status_block, + u_status_block); + sb->u_status_block.status_block_id = id; + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section)); + REG_WR(bp, BAR_USTRORM_INTMEM + + ((USTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4), + U64_HI(section)); + + for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_USTRORM_INTMEM + + USTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1); + + /* CSTORM */ + section = ((u64)mapping) + offsetof(struct host_status_block, + c_status_block); + sb->c_status_block.status_block_id = id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_SB_HOST_SB_ADDR_OFFSET(port, id)) + 4), + U64_HI(section)); + + for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_OFFSET(port, id, index), 0x1); + + bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +} + +static void bnx2x_init_def_sb(struct bnx2x *bp, + struct host_def_status_block *def_sb, + dma_addr_t mapping, int id) +{ + int port = bp->port; + int index, val, reg_offset; + u64 section; + + /* ATTN */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + atten_status_block); + def_sb->atten_status_block.status_block_id = id; + + reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : + MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); + + for (index = 0; index < 3; 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); + } + + bp->aeu_mask = REG_RD(bp, (port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : + MISC_REG_AEU_MASK_ATTN_FUNC_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)); + + reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); + + val = REG_RD(bp, reg_offset); + val |= id; + REG_WR(bp, reg_offset, val); + + /* USTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + u_def_status_block); + def_sb->u_def_status_block.status_block_id = id; + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); + REG_WR(bp, BAR_USTRORM_INTMEM + + ((USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4), + U64_HI(section)); + REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_HC_BTR_OFFSET(port), + BNX2X_BTR); + + for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_USTRORM_INTMEM + + USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + + /* CSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + c_def_status_block); + def_sb->c_def_status_block.status_block_id = id; + + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + + ((CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4), + U64_HI(section)); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_OFFSET(port), + BNX2X_BTR); + + for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + + /* TSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + t_def_status_block); + def_sb->t_def_status_block.status_block_id = id; + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); + REG_WR(bp, BAR_TSTRORM_INTMEM + + ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4), + U64_HI(section)); + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), + BNX2X_BTR); + + for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_TSTRORM_INTMEM + + TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + + /* XSTORM */ + section = ((u64)mapping) + offsetof(struct host_def_status_block, + x_def_status_block); + def_sb->x_def_status_block.status_block_id = id; + + REG_WR(bp, BAR_XSTRORM_INTMEM + + XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port), U64_LO(section)); + REG_WR(bp, BAR_XSTRORM_INTMEM + + ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)) + 4), + U64_HI(section)); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), + BNX2X_BTR); + + for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) + REG_WR16(bp, BAR_XSTRORM_INTMEM + + XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index), 0x1); + + bnx2x_ack_sb(bp, id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); +} + +static void bnx2x_update_coalesce(struct bnx2x *bp) +{ + int port = bp->port; + int i; + + for_each_queue(bp, i) { + + /* HC_INDEX_U_ETH_RX_CQ_CONS */ + REG_WR8(bp, BAR_USTRORM_INTMEM + + USTORM_SB_HC_TIMEOUT_OFFSET(port, i, + HC_INDEX_U_ETH_RX_CQ_CONS), + bp->rx_ticks_int/12); + REG_WR16(bp, BAR_USTRORM_INTMEM + + USTORM_SB_HC_DISABLE_OFFSET(port, i, + HC_INDEX_U_ETH_RX_CQ_CONS), + bp->rx_ticks_int ? 0 : 1); + + /* HC_INDEX_C_ETH_TX_CQ_CONS */ + REG_WR8(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_TIMEOUT_OFFSET(port, i, + HC_INDEX_C_ETH_TX_CQ_CONS), + bp->tx_ticks_int/12); + REG_WR16(bp, BAR_CSTRORM_INTMEM + + CSTORM_SB_HC_DISABLE_OFFSET(port, i, + HC_INDEX_C_ETH_TX_CQ_CONS), + bp->tx_ticks_int ? 0 : 1); + } +} + +static void bnx2x_init_rx_rings(struct bnx2x *bp) +{ + u16 ring_prod; + int i, j; + int port = bp->port; + + bp->rx_buf_use_size = bp->dev->mtu; + + bp->rx_buf_use_size += bp->rx_offset + ETH_OVREHEAD; + bp->rx_buf_size = bp->rx_buf_use_size + 64; + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + fp->rx_bd_cons = 0; + fp->rx_cons_sb = BNX2X_RX_SB_INDEX; + + 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))); + + } + + 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))); + } + + /* rx completion queue */ + fp->rx_comp_cons = 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\n", i); + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + BUG_TRAP(ring_prod > i); + } + + fp->rx_bd_prod = fp->rx_comp_prod = ring_prod; + fp->rx_pkt = fp->rx_calls = 0; + + /* Warning! this will genrate an interrupt (to the TSTORM) */ + /* must only be done when chip is initialized */ + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_RCQ_PROD_OFFSET(port, j), ring_prod); + if (j != 0) + continue; + + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port) + 4, + U64_HI(fp->rx_comp_mapping)); + } +} + +static void bnx2x_init_tx_ring(struct bnx2x *bp) +{ + int i, j; + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + for (i = 1; i <= NUM_TX_RINGS; i++) { + struct eth_tx_bd *tx_bd = + &fp->tx_desc_ring[TX_DESC_CNT * i - 1]; + + tx_bd->addr_hi = + cpu_to_le32(U64_HI(fp->tx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); + tx_bd->addr_lo = + cpu_to_le32(U64_LO(fp->tx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); + } + + fp->tx_pkt_prod = 0; + 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 void bnx2x_init_sp_ring(struct bnx2x *bp) +{ + int port = bp->port; + + spin_lock_init(&bp->spq_lock); + + bp->spq_left = MAX_SPQ_PENDING; + bp->spq_prod_idx = 0; + bp->dsb_sp_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, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port), + U64_LO(bp->spq_mapping)); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PAGE_BASE_OFFSET(port) + 4, + U64_HI(bp->spq_mapping)); + + REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(port), + bp->spq_prod_idx); +} + +static void bnx2x_init_context(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) { + struct eth_context *context = bnx2x_sp(bp, context[i].eth); + struct bnx2x_fastpath *fp = &bp->fp[i]; + + 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.db_data_addr_hi = + U64_HI(fp->tx_prods_mapping); + context->xstorm_st_context.db_data_addr_lo = + U64_LO(fp->tx_prods_mapping); + + context->ustorm_st_context.rx_bd_page_base_hi = + U64_HI(fp->rx_desc_mapping); + context->ustorm_st_context.rx_bd_page_base_lo = + U64_LO(fp->rx_desc_mapping); + context->ustorm_st_context.status_block_id = i; + context->ustorm_st_context.sb_index_number = + HC_INDEX_U_ETH_RX_CQ_CONS; + context->ustorm_st_context.rcq_base_address_hi = + U64_HI(fp->rx_comp_mapping); + context->ustorm_st_context.rcq_base_address_lo = + U64_LO(fp->rx_comp_mapping); + context->ustorm_st_context.flags = + USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT; + context->ustorm_st_context.mc_alignment_size = 64; + context->ustorm_st_context.num_rss = bp->num_queues; + + context->cstorm_st_context.sb_index_number = + HC_INDEX_C_ETH_TX_CQ_CONS; + context->cstorm_st_context.status_block_id = i; + + context->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), + CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); + context->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), + CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + } +} + +static void bnx2x_init_ind_table(struct bnx2x *bp) +{ + int port = bp->port; + int i; + + if (!is_multi(bp)) + return; + + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++) + REG_WR8(bp, TSTORM_INDIRECTION_TABLE_OFFSET(port) + i, + i % bp->num_queues); + + REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); +} + +static void bnx2x_set_storm_rx_mode(struct bnx2x *bp) +{ + int mode = bp->rx_mode; + int port = bp->port; + struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; + int i; + + DP(NETIF_MSG_RX_STATUS, "rx mode is %d\n", mode); + + switch (mode) { + case BNX2X_RX_MODE_NONE: /* no Rx */ + tstorm_mac_filter.ucast_drop_all = 1; + tstorm_mac_filter.mcast_drop_all = 1; + tstorm_mac_filter.bcast_drop_all = 1; + break; + case BNX2X_RX_MODE_NORMAL: + tstorm_mac_filter.bcast_accept_all = 1; + break; + case BNX2X_RX_MODE_ALLMULTI: + tstorm_mac_filter.mcast_accept_all = 1; + tstorm_mac_filter.bcast_accept_all = 1; + break; + case BNX2X_RX_MODE_PROMISC: + tstorm_mac_filter.ucast_accept_all = 1; + tstorm_mac_filter.mcast_accept_all = 1; + tstorm_mac_filter.bcast_accept_all = 1; + break; + default: + BNX2X_ERR("bad rx mode (%d)\n", mode); + } + + for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(port) + i * 4, + ((u32 *)&tstorm_mac_filter)[i]); + +/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, + ((u32 *)&tstorm_mac_filter)[i]); */ + } +} + +static void bnx2x_set_client_config(struct bnx2x *bp, int client_id) +{ +#ifdef BCM_VLAN + int mode = bp->rx_mode; +#endif + int port = bp->port; + struct tstorm_eth_client_config tstorm_client = {0}; + + tstorm_client.mtu = bp->dev->mtu; + tstorm_client.statistics_counter_id = 0; + tstorm_client.config_flags = + TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; +#ifdef BCM_VLAN + if (mode && bp->vlgrp) { + tstorm_client.config_flags |= + TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + } +#endif + tstorm_client.drop_flags = (TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR | + TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR | + TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR | + TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR); + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, client_id), + ((u32 *)&tstorm_client)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) + 4, + ((u32 *)&tstorm_client)[1]); + +/* DP(NETIF_MSG_IFUP, "tstorm_client: 0x%08x 0x%08x\n", + ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); */ +} + +static void bnx2x_init_internal(struct bnx2x *bp) +{ + int port = bp->port; + struct tstorm_eth_function_common_config tstorm_config = {0}; + struct stats_indication_flags stats_flags = {0}; + int i; + + if (is_multi(bp)) { + tstorm_config.config_flags = MULTI_FLAGS; + tstorm_config.rss_result_mask = MULTI_MASK; + } + + REG_WR(bp, BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(port), + (*(u32 *)&tstorm_config)); + +/* DP(NETIF_MSG_IFUP, "tstorm_config: 0x%08x\n", + (*(u32 *)&tstorm_config)); */ + + bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx untill link is up */ + bnx2x_set_storm_rx_mode(bp); + + for_each_queue(bp, i) + bnx2x_set_client_config(bp, i); + + + stats_flags.collect_eth = cpu_to_le32(1); + + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(port) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(port) + 4, + ((u32 *)&stats_flags)[1]); + + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port), + ((u32 *)&stats_flags)[0]); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(port) + 4, + ((u32 *)&stats_flags)[1]); + +/* DP(NETIF_MSG_IFUP, "stats_flags: 0x%08x 0x%08x\n", + ((u32 *)&stats_flags)[0], ((u32 *)&stats_flags)[1]); */ +} + +static void bnx2x_nic_init(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + fp->state = BNX2X_FP_STATE_CLOSED; + DP(NETIF_MSG_IFUP, "bnx2x_init_sb(%p,%p,%d);\n", + bp, fp->status_blk, i); + fp->index = i; + bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, i); + } + + bnx2x_init_def_sb(bp, bp->def_status_blk, + bp->def_status_blk_mapping, 0x10); + bnx2x_update_coalesce(bp); + bnx2x_init_rx_rings(bp); + bnx2x_init_tx_ring(bp); + bnx2x_init_sp_ring(bp); + bnx2x_init_context(bp); + bnx2x_init_internal(bp); + bnx2x_init_stats(bp); + bnx2x_init_ind_table(bp); + bnx2x_enable_int(bp); + +} + +/* end of nic init */ + +/* + * gzip service functions + */ + +static int bnx2x_gunzip_init(struct bnx2x *bp) +{ + bp->gunzip_buf = pci_alloc_consistent(bp->pdev, FW_BUF_SIZE, + &bp->gunzip_mapping); + if (bp->gunzip_buf == NULL) + goto gunzip_nomem1; + + bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL); + if (bp->strm == NULL) + goto gunzip_nomem2; + + bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), + GFP_KERNEL); + if (bp->strm->workspace == NULL) + goto gunzip_nomem3; + + return 0; + +gunzip_nomem3: + kfree(bp->strm); + bp->strm = NULL; + +gunzip_nomem2: + pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf, + bp->gunzip_mapping); + bp->gunzip_buf = NULL; + +gunzip_nomem1: + printk(KERN_ERR PFX "%s: Cannot allocate firmware buffer for" + " uncompression\n", bp->dev->name); + return -ENOMEM; +} + +static void bnx2x_gunzip_end(struct bnx2x *bp) +{ + kfree(bp->strm->workspace); + + kfree(bp->strm); + bp->strm = NULL; + + if (bp->gunzip_buf) { + pci_free_consistent(bp->pdev, FW_BUF_SIZE, bp->gunzip_buf, + bp->gunzip_mapping); + bp->gunzip_buf = NULL; + } +} + +static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len) +{ + int n, rc; + + /* check gzip header */ + if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) + return -EINVAL; + + n = 10; + +#define FNAME 0x8 + + if (zbuf[3] & FNAME) + while ((zbuf[n++] != 0) && (n < len)); + + bp->strm->next_in = zbuf + n; + bp->strm->avail_in = len - n; + bp->strm->next_out = bp->gunzip_buf; + bp->strm->avail_out = FW_BUF_SIZE; + + rc = zlib_inflateInit2(bp->strm, -MAX_WBITS); + if (rc != Z_OK) + return rc; + + rc = zlib_inflate(bp->strm, Z_FINISH); + if ((rc != Z_OK) && (rc != Z_STREAM_END)) + printk(KERN_ERR PFX "%s: Firmware decompression error: %s\n", + bp->dev->name, bp->strm->msg); + + bp->gunzip_outlen = (FW_BUF_SIZE - bp->strm->avail_out); + if (bp->gunzip_outlen & 0x3) + printk(KERN_ERR PFX "%s: Firmware decompression error:" + " gunzip_outlen (%d) not aligned\n", + bp->dev->name, bp->gunzip_outlen); + bp->gunzip_outlen >>= 2; + + zlib_inflateEnd(bp->strm); + + if (rc == Z_STREAM_END) + return 0; + + return rc; +} + +/* nic load/unload */ + +/* + * general service functions + */ + +/* send a NIG loopback debug packet */ +static void bnx2x_lb_pckt(struct bnx2x *bp) +{ +#ifdef USE_DMAE + u32 wb_write[3]; +#endif + + /* Ethernet source and destination addresses */ +#ifdef USE_DMAE + wb_write[0] = 0x55555555; + wb_write[1] = 0x55555555; + wb_write[2] = 0x20; /* SOP */ + REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); +#else + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x55555555); + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555); + /* SOP */ + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x20); +#endif + + /* NON-IP protocol */ +#ifdef USE_DMAE + wb_write[0] = 0x09000000; + wb_write[1] = 0x55555555; + wb_write[2] = 0x10; /* EOP, eop_bvalid = 0 */ + REG_WR_DMAE(bp, NIG_REG_DEBUG_PACKET_LB, wb_write, 3); +#else + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB, 0x09000000); + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 4, 0x55555555); + /* EOP, eop_bvalid = 0 */ + REG_WR_IND(bp, NIG_REG_DEBUG_PACKET_LB + 8, 0x10); +#endif +} + +/* some of the internal memories + * are not directly readable from the driver + * to test them we send debug packets + */ +static int bnx2x_int_mem_test(struct bnx2x *bp) +{ + int factor; + int count, i; + u32 val = 0; + + switch (CHIP_REV(bp)) { + case CHIP_REV_EMUL: + factor = 200; + break; + case CHIP_REV_FPGA: + factor = 120; + break; + default: + factor = 1; + break; + } + + 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); + REG_WR(bp, CFC_REG_DEBUG0, 0x1); + NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0); + + /* Write 0 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + + /* send Ethernet packet */ + bnx2x_lb_pckt(bp); + + /* TODO do i reset NIG statistic? */ + /* Wait until NIG register shows 1 packet of size 0x10 */ + count = 1000 * factor; + while (count) { +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); +#else + val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET); + REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4); +#endif + if (val == 0x10) + break; + + msleep(10); + count--; + } + if (val != 0x10) { + BNX2X_ERR("NIG timeout val = 0x%x\n", val); + return -1; + } + + /* Wait until PRS register shows 1 packet */ + count = 1000 * factor; + while (count) { + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + + if (val == 1) + break; + + msleep(10); + count--; + } + if (val != 0x1) { + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + return -2; + } + + /* Reset and init BRB, PRS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x3); + msleep(50); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x3); + msleep(50); + bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); + bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + + DP(NETIF_MSG_HW, "part2\n"); + + /* Disable inputs of parser neighbor blocks */ + REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); + REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); + REG_WR(bp, CFC_REG_DEBUG0, 0x1); + NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x0); + + /* Write 0 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x0); + + /* send 10 Ethernet packets */ + for (i = 0; i < 10; i++) + bnx2x_lb_pckt(bp); + + /* Wait until NIG register shows 10 + 1 + packets of size 11*0x10 = 0xb0 */ + count = 1000 * factor; + while (count) { +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); +#else + val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET); + REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4); +#endif + if (val == 0xb0) + break; + + msleep(10); + count--; + } + if (val != 0xb0) { + BNX2X_ERR("NIG timeout val = 0x%x\n", val); + return -3; + } + + /* Wait until PRS register shows 2 packets */ + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + if (val != 2) + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + + /* Write 1 to parser credits for CFC search request */ + REG_WR(bp, PRS_REG_CFC_SEARCH_INITIAL_CREDIT, 0x1); + + /* Wait until PRS register shows 3 packets */ + msleep(10 * factor); + /* Wait until NIG register shows 1 packet of size 0x10 */ + val = REG_RD(bp, PRS_REG_NUM_OF_PACKETS); + if (val != 3) + BNX2X_ERR("PRS timeout val = 0x%x\n", val); + + /* clear NIG EOP FIFO */ + for (i = 0; i < 11; i++) + REG_RD(bp, NIG_REG_INGRESS_EOP_LB_FIFO); + val = REG_RD(bp, NIG_REG_INGRESS_EOP_LB_EMPTY); + if (val != 1) { + BNX2X_ERR("clear of NIG failed\n"); + return -4; + } + + /* Reset and init BRB, PRS, NIG */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x03); + msleep(50); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03); + msleep(50); + bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); + bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); +#ifndef BCM_ISCSI + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif + + /* Enable inputs of parser neighbor blocks */ + REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x7fffffff); + REG_WR(bp, TCM_REG_PRS_IFEN, 0x1); + REG_WR(bp, CFC_REG_DEBUG0, 0x0); + NIG_WR(NIG_REG_PRS_REQ_IN_EN, 0x1); + + DP(NETIF_MSG_HW, "done\n"); + + return 0; /* OK */ +} + +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); + REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); + REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + 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); + REG_WR(bp, XSDM_REG_XSDM_INT_MASK_1, 0); + REG_WR(bp, XCM_REG_XCM_INT_MASK, 0); +/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_0, 0); */ +/* REG_WR(bp, XSEM_REG_XSEM_INT_MASK_1, 0); */ + REG_WR(bp, USDM_REG_USDM_INT_MASK_0, 0); + REG_WR(bp, USDM_REG_USDM_INT_MASK_1, 0); + REG_WR(bp, UCM_REG_UCM_INT_MASK, 0); +/* REG_WR(bp, USEM_REG_USEM_INT_MASK_0, 0); */ +/* REG_WR(bp, USEM_REG_USEM_INT_MASK_1, 0); */ + REG_WR(bp, GRCBASE_UPB + PB_REG_PB_INT_MASK, 0); + REG_WR(bp, CSDM_REG_CSDM_INT_MASK_0, 0); + REG_WR(bp, CSDM_REG_CSDM_INT_MASK_1, 0); + 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); */ + REG_WR(bp, PXP2_REG_PXP2_INT_MASK, 0x480000); + REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); + REG_WR(bp, TSDM_REG_TSDM_INT_MASK_1, 0); + REG_WR(bp, TCM_REG_TCM_INT_MASK, 0); +/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_0, 0); */ +/* REG_WR(bp, TSEM_REG_TSEM_INT_MASK_1, 0); */ + REG_WR(bp, CDU_REG_CDU_INT_MASK, 0); + REG_WR(bp, DMAE_REG_DMAE_INT_MASK, 0); +/* REG_WR(bp, MISC_REG_MISC_INT_MASK, 0); */ + REG_WR(bp, PBF_REG_PBF_INT_MASK, 0X18); /* bit 3,4 masked */ +} + +static int bnx2x_function_init(struct bnx2x *bp, int mode) +{ + int func = bp->port; + int port = func ? PORT1 : PORT0; + u32 val, i; +#ifdef USE_DMAE + u32 wb_write[2]; +#endif + + DP(BNX2X_MSG_MCP, "function is %d mode is %x\n", func, mode); + if ((func != 0) && (func != 1)) { + BNX2X_ERR("BAD function number (%d)\n", func); + return -ENODEV; + } + + bnx2x_gunzip_init(bp); + + if (mode & 0x1) { /* init common */ + DP(BNX2X_MSG_MCP, "starting common init func %d mode %x\n", + func, mode); + REG_WR(bp, MISC_REG_RESET_REG_1, 0xffffffff); + REG_WR(bp, MISC_REG_RESET_REG_2, 0xfffc); + bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END); + + REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); + msleep(30); + REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + + bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END); + bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END); + + bnx2x_init_pxp(bp); + + if (CHIP_REV(bp) == CHIP_REV_Ax) { + /* enable HW interrupt from PXP on USDM + overflow bit 16 on INT_MASK_0 */ + REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); + } + +#ifdef __BIG_ENDIAN + REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1); + REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 1); + +/* REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */ + REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1); + REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); +#endif + +#ifndef BCM_ISCSI + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif + + REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 5); +#ifdef BCM_ISCSI + 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_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END); + + /* let the HW do it's magic ... */ + msleep(100); + /* finish PXP init + (can be moved up if we want to use the DMAE) */ + val = REG_RD(bp, PXP2_REG_RQ_CFG_DONE); + if (val != 1) { + BNX2X_ERR("PXP2 CFG failed\n"); + return -EBUSY; + } + + val = REG_RD(bp, PXP2_REG_RD_INIT_DONE); + if (val != 1) { + BNX2X_ERR("PXP2 RD_INIT failed\n"); + return -EBUSY; + } + + REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); + REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + + bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8); + + bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END); + bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END); + bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END); + bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END); + +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3); + bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3); +#else + REG_RD(bp, XSEM_REG_PASSIVE_BUFFER); + REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 4); + REG_RD(bp, XSEM_REG_PASSIVE_BUFFER + 8); + REG_RD(bp, CSEM_REG_PASSIVE_BUFFER); + REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 4); + REG_RD(bp, CSEM_REG_PASSIVE_BUFFER + 8); + REG_RD(bp, TSEM_REG_PASSIVE_BUFFER); + REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 4); + REG_RD(bp, TSEM_REG_PASSIVE_BUFFER + 8); + REG_RD(bp, USEM_REG_PASSIVE_BUFFER); + REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 4); + REG_RD(bp, USEM_REG_PASSIVE_BUFFER + 8); +#endif + bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END); + /* softrest pulse */ + REG_WR(bp, QM_REG_SOFT_RESET, 1); + REG_WR(bp, QM_REG_SOFT_RESET, 0); + +#ifdef BCM_ISCSI + bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END); +#endif + bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END); + REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_BITS); + if (CHIP_REV(bp) == CHIP_REV_Ax) { + /* enable hw interrupt from doorbell Q */ + REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); + } + + bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END); + + if (CHIP_REV_IS_SLOW(bp)) { + /* fix for emulation and FPGA for no pause */ + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 513); + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 513); + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0); + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0); + } + + bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END); + + bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END); + bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END); + bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END); + bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END); + + bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); + bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); + bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); + bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); + + bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END); + bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END); + bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END); + bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END); + + /* sync semi rtc */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0x80000000); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, + 0x80000000); + + bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END); + bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END); + bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END); + + 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, 0xc0cac01a); + /* TODO: repleace with something meaningfull */ + } + /* SRCH COMMON comes here */ + REG_WR(bp, SRC_REG_SOFT_RST, 0); + + if (sizeof(union cdu_context) != 1024) { + /* we currently assume that a context is 1024 bytes */ + printk(KERN_ALERT PFX "please adjust the size of" + " cdu_context(%ld)\n", + (long)sizeof(union cdu_context)); + } + val = (4 << 24) + (0 << 12) + 1024; + REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val); + bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END); + + bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END); + REG_WR(bp, CFC_REG_INIT_REG, 0x7FF); + + bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END); + bnx2x_init_block(bp, MISC_AEU_COMMON_START, + MISC_AEU_COMMON_END); + /* RXPCS COMMON comes here */ + /* EMAC0 COMMON comes here */ + /* EMAC1 COMMON comes here */ + /* DBU COMMON comes here */ + /* DBG COMMON comes here */ + bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END); + + if (CHIP_REV_IS_SLOW(bp)) + msleep(200); + + /* finish CFC init */ + val = REG_RD(bp, CFC_REG_LL_INIT_DONE); + if (val != 1) { + BNX2X_ERR("CFC LL_INIT failed\n"); + return -EBUSY; + } + + val = REG_RD(bp, CFC_REG_AC_INIT_DONE); + if (val != 1) { + BNX2X_ERR("CFC AC_INIT failed\n"); + return -EBUSY; + } + + val = REG_RD(bp, CFC_REG_CAM_INIT_DONE); + if (val != 1) { + BNX2X_ERR("CFC CAM_INIT failed\n"); + return -EBUSY; + } + + REG_WR(bp, CFC_REG_DEBUG0, 0); + + /* read NIG statistic + to see if this is our first up since powerup */ +#ifdef BNX2X_DMAE_RD + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); +#else + val = REG_RD(bp, NIG_REG_STAT2_BRB_OCTET); + REG_RD(bp, NIG_REG_STAT2_BRB_OCTET + 4); +#endif + /* do internal memory self test */ + if ((val == 0) && bnx2x_int_mem_test(bp)) { + BNX2X_ERR("internal mem selftest failed\n"); + return -EBUSY; + } + + /* clear PXP2 attentions */ + REG_RD(bp, PXP2_REG_PXP2_INT_STS_CLR); + + enable_blocks_attention(bp); + /* enable_blocks_parity(bp); */ + + } /* end of common init */ + + /* per port init */ + + /* 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 RQ_ONCHIP_AT_PORT_SIZE 384 +#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) + + DP(BNX2X_MSG_MCP, "starting per-function init port is %x\n", func); + + REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + func*4, 0); + + /* Port PXP comes here */ + /* Port PXP2 comes here */ + + /* Offset is + * Port0 0 + * Port1 384 */ + i = func * RQ_ONCHIP_AT_PORT_SIZE; +#ifdef USE_DMAE + wb_write[0] = ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context)); + wb_write[1] = ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context)); + REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2); +#else + REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, + ONCHIP_ADDR1(bnx2x_sp_mapping(bp, context))); + REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + i*8 + 4, + ONCHIP_ADDR2(bnx2x_sp_mapping(bp, context))); +#endif + REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, PXP_ONE_ILT(i)); + +#ifdef BCM_ISCSI + /* Port0 1 + * Port1 385 */ + i++; + wb_write[0] = ONCHIP_ADDR1(bp->timers_mapping); + wb_write[1] = ONCHIP_ADDR2(bp->timers_mapping); + REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2); + REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); + + /* Port0 2 + * Port1 386 */ + i++; + wb_write[0] = ONCHIP_ADDR1(bp->qm_mapping); + wb_write[1] = ONCHIP_ADDR2(bp->qm_mapping); + REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2); + REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); + + /* Port0 3 + * Port1 387 */ + i++; + wb_write[0] = ONCHIP_ADDR1(bp->t1_mapping); + wb_write[1] = ONCHIP_ADDR2(bp->t1_mapping); + REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2); + REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); +#endif + + /* Port TCM comes here */ + /* Port UCM comes here */ + /* Port CCM comes here */ + bnx2x_init_block(bp, func ? XCM_PORT1_START : XCM_PORT0_START, + func ? XCM_PORT1_END : XCM_PORT0_END); + +#ifdef USE_DMAE + wb_write[0] = 0; + wb_write[1] = 0; +#endif + for (i = 0; i < 32; i++) { + REG_WR(bp, QM_REG_BASEADDR + (func*32 + i)*4, 1024 * 4 * i); +#ifdef USE_DMAE + REG_WR_DMAE(bp, QM_REG_PTRTBL + (func*32 + i)*8, wb_write, 2); +#else + REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8, 0); + REG_WR_IND(bp, QM_REG_PTRTBL + (func*32 + i)*8 + 4, 0); +#endif + } + REG_WR(bp, QM_REG_CONNNUM_0 + func*4, 1024/16 - 1); + + /* Port QM comes here */ + +#ifdef BCM_ISCSI + REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20); + REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31); + + bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START, + func ? TIMERS_PORT1_END : TIMERS_PORT0_END); +#endif + /* Port DQ comes here */ + /* Port BRB1 comes here */ + bnx2x_init_block(bp, func ? PRS_PORT1_START : PRS_PORT0_START, + func ? PRS_PORT1_END : PRS_PORT0_END); + /* Port TSDM comes here */ + /* Port CSDM comes here */ + /* Port USDM comes here */ + /* Port XSDM comes here */ + bnx2x_init_block(bp, func ? TSEM_PORT1_START : TSEM_PORT0_START, + func ? TSEM_PORT1_END : TSEM_PORT0_END); + bnx2x_init_block(bp, func ? USEM_PORT1_START : USEM_PORT0_START, + func ? USEM_PORT1_END : USEM_PORT0_END); + bnx2x_init_block(bp, func ? CSEM_PORT1_START : CSEM_PORT0_START, + func ? CSEM_PORT1_END : CSEM_PORT0_END); + bnx2x_init_block(bp, func ? XSEM_PORT1_START : XSEM_PORT0_START, + func ? XSEM_PORT1_END : XSEM_PORT0_END); + /* Port UPB comes here */ + /* Port XSDM comes here */ + bnx2x_init_block(bp, func ? PBF_PORT1_START : PBF_PORT0_START, + func ? PBF_PORT1_END : PBF_PORT0_END); + + /* configure PBF to work without PAUSE mtu 9000 */ + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + func*4, 0); + + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + func*4, (9040/16)); + /* update init credit */ + REG_WR(bp, PBF_REG_P0_INIT_CRD + func*4, (9040/16) + 553 - 22); + + /* probe changes */ + REG_WR(bp, PBF_REG_INIT_P0 + func*4, 1); + msleep(5); + REG_WR(bp, PBF_REG_INIT_P0 + func*4, 0); + +#ifdef BCM_ISCSI + /* tell the searcher where the T2 table is */ + REG_WR(bp, SRC_REG_COUNTFREE0 + func*4, 16*1024/64); + + wb_write[0] = U64_LO(bp->t2_mapping); + wb_write[1] = U64_HI(bp->t2_mapping); + REG_WR_DMAE(bp, SRC_REG_FIRSTFREE0 + func*4, wb_write, 2); + wb_write[0] = U64_LO((u64)bp->t2_mapping + 16*1024 - 64); + wb_write[1] = U64_HI((u64)bp->t2_mapping + 16*1024 - 64); + REG_WR_DMAE(bp, SRC_REG_LASTFREE0 + func*4, wb_write, 2); + + REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + func*4, 10); + /* Port SRCH comes here */ +#endif + /* Port CDU comes here */ + /* Port CFC comes here */ + bnx2x_init_block(bp, func ? HC_PORT1_START : HC_PORT0_START, + func ? HC_PORT1_END : HC_PORT0_END); + bnx2x_init_block(bp, func ? MISC_AEU_PORT1_START : + MISC_AEU_PORT0_START, + func ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END); + /* Port PXPCS comes here */ + /* Port EMAC0 comes here */ + /* Port EMAC1 comes here */ + /* Port DBU comes here */ + /* Port DBG comes here */ + bnx2x_init_block(bp, func ? NIG_PORT1_START : NIG_PORT0_START, + func ? NIG_PORT1_END : NIG_PORT0_END); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + func*4, 1); + /* Port MCP comes here */ + /* Port DMAE comes here */ + + bnx2x_link_reset(bp); + + /* Reset pciex errors for debug */ + REG_WR(bp, 0x2114, 0xffffffff); + REG_WR(bp, 0x2120, 0xffffffff); + REG_WR(bp, 0x2814, 0xffffffff); + + /* !!! move to init_values.h */ + REG_WR(bp, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1); + REG_WR(bp, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1); + REG_WR(bp, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1); + REG_WR(bp, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1); + + REG_WR(bp, DBG_REG_PCI_REQ_CREDIT, 0x1); + REG_WR(bp, TM_REG_PCIARB_CRDCNT_VAL, 0x1); + REG_WR(bp, CDU_REG_CDU_DEBUG, 0x264); + REG_WR(bp, CDU_REG_CDU_DEBUG, 0x0); + + bnx2x_gunzip_end(bp); + + if (!nomcp) { + port = bp->port; + + bp->fw_drv_pulse_wr_seq = + (SHMEM_RD(bp, drv_fw_mb[port].drv_pulse_mb) & + DRV_PULSE_SEQ_MASK); + bp->fw_mb = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_param); + DP(BNX2X_MSG_MCP, "drv_pulse 0x%x fw_mb 0x%x\n", + bp->fw_drv_pulse_wr_seq, bp->fw_mb); + } else { + bp->fw_mb = 0; + } + + return 0; +} + + +/* send the MCP a request, block untill there is a reply */ +static u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) +{ + u32 rc = 0; + u32 seq = ++bp->fw_seq; + int port = bp->port; + + SHMEM_WR(bp, drv_fw_mb[port].drv_mb_header, command|seq); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", command|seq); + + /* let the FW do it's magic ... */ + msleep(100); /* TBD */ + + if (CHIP_REV_IS_SLOW(bp)) + msleep(900); + + rc = SHMEM_RD(bp, drv_fw_mb[port].fw_mb_header); + + DP(BNX2X_MSG_MCP, "read (%x) seq is (%x) from FW MB\n", rc, seq); + + /* is this a reply to our command? */ + if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) { + rc &= FW_MSG_CODE_MASK; + } else { + /* FW BUG! */ + BNX2X_ERR("FW failed to respond!\n"); + bnx2x_fw_dump(bp); + rc = 0; + } + return rc; +} + +static void bnx2x_free_mem(struct bnx2x *bp) +{ + +#define BNX2X_PCI_FREE(x, y, size) \ + do { \ + if (x) { \ + pci_free_consistent(bp->pdev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define BNX2X_FREE(x) \ + do { \ + if (x) { \ + vfree(x); \ + x = NULL; \ + } \ + } while (0) + + int i; + + /* fastpath */ + 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) + + sizeof(struct eth_tx_db_data)); + + /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */ + BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring)); + BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring), + bnx2x_fp(bp, i, tx_desc_mapping), + sizeof(struct eth_tx_bd) * NUM_TX_BD); + + BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring)); + BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring), + bnx2x_fp(bp, i, rx_desc_mapping), + sizeof(struct eth_rx_bd) * NUM_RX_BD); + + BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring), + bnx2x_fp(bp, i, rx_comp_mapping), + sizeof(struct eth_fast_path_rx_cqe) * + NUM_RCQ_BD); + } + + BNX2X_FREE(bp->fp); + + /* end of fastpath */ + + BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, + (sizeof(struct host_def_status_block))); + + BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, + (sizeof(struct bnx2x_slowpath))); + +#ifdef BCM_ISCSI + 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); +#endif + BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, PAGE_SIZE); + +#undef BNX2X_PCI_FREE +#undef BNX2X_KFREE +} + +static int bnx2x_alloc_mem(struct bnx2x *bp) +{ + +#define BNX2X_PCI_ALLOC(x, y, size) \ + do { \ + x = pci_alloc_consistent(bp->pdev, size, y); \ + if (x == NULL) \ + goto alloc_mem_err; \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ALLOC(x, size) \ + do { \ + x = vmalloc(size); \ + if (x == NULL) \ + goto alloc_mem_err; \ + memset(x, 0, size); \ + } while (0) + + int i; + + /* fastpath */ + BNX2X_ALLOC(bp->fp, sizeof(struct bnx2x_fastpath) * bp->num_queues); + + for_each_queue(bp, i) { + bnx2x_fp(bp, i, bp) = bp; + + /* Status blocks */ + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_status_block) + + sizeof(struct eth_tx_db_data)); + + bnx2x_fp(bp, i, hw_tx_prods) = + (void *)(bnx2x_fp(bp, i, status_blk) + 1); + + bnx2x_fp(bp, i, tx_prods_mapping) = + bnx2x_fp(bp, i, status_blk_mapping) + + sizeof(struct host_status_block); + + /* fast path rings: tx_buf tx_desc rx_buf rx_desc rx_comp */ + BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring), + sizeof(struct sw_tx_bd) * NUM_TX_BD); + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring), + &bnx2x_fp(bp, i, tx_desc_mapping), + sizeof(struct eth_tx_bd) * NUM_TX_BD); + + BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring), + sizeof(struct sw_rx_bd) * NUM_RX_BD); + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring), + &bnx2x_fp(bp, i, rx_desc_mapping), + sizeof(struct eth_rx_bd) * NUM_RX_BD); + + BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring), + &bnx2x_fp(bp, i, rx_comp_mapping), + sizeof(struct eth_fast_path_rx_cqe) * + NUM_RCQ_BD); + + } + /* end of fastpath */ + + BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, + sizeof(struct host_def_status_block)); + + BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, + sizeof(struct bnx2x_slowpath)); + +#ifdef BCM_ISCSI + BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); + + /* Initialize T1 */ + for (i = 0; i < 64*1024; i += 64) { + *(u64 *)((char *)bp->t1 + i + 56) = 0x0UL; + *(u64 *)((char *)bp->t1 + i + 3) = 0x0UL; + } + + /* 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 (i = 0; i < 16*1024; i += 64) + * (u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + + /* now sixup the last line in the block to point to the next block */ + *(u64 *)((char *)bp->t2 + 1024*16-8) = bp->t2_mapping; + + /* Timer block array (MAX_CONN*8) phys uncached for now 1024 conns */ + BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + + /* QM queues (128*MAX_CONN) */ + BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); +#endif + + /* Slow path ring */ + BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); + + return 0; + +alloc_mem_err: + bnx2x_free_mem(bp); + return -ENOMEM; + +#undef BNX2X_PCI_ALLOC +#undef BNX2X_ALLOC +} + +static void bnx2x_free_tx_skbs(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + + u16 bd_cons = fp->tx_bd_cons; + u16 sw_prod = fp->tx_pkt_prod; + u16 sw_cons = fp->tx_pkt_cons; + + BUG_TRAP(fp->tx_buf_ring != NULL); + + while (sw_cons != sw_prod) { + bd_cons = bnx2x_free_tx_pkt(bp, fp, TX_BD(sw_cons)); + sw_cons++; + } + } +} + +static void bnx2x_free_rx_skbs(struct bnx2x *bp) +{ + int i, j; + + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + + BUG_TRAP(fp->rx_buf_ring != NULL); + + for (i = 0; i < NUM_RX_BD; i++) { + struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i]; + struct sk_buff *skb = rx_buf->skb; + + if (skb == NULL) + continue; + + pci_unmap_single(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + bp->rx_buf_use_size, + PCI_DMA_FROMDEVICE); + + rx_buf->skb = NULL; + dev_kfree_skb(skb); + } + } +} + +static void bnx2x_free_skbs(struct bnx2x *bp) +{ + bnx2x_free_tx_skbs(bp); + bnx2x_free_rx_skbs(bp); +} + +static void bnx2x_free_msix_irqs(struct bnx2x *bp) +{ + int i; + + free_irq(bp->msix_table[0].vector, bp->dev); + DP(NETIF_MSG_IFDOWN, "rleased sp irq (%d)\n", + bp->msix_table[0].vector); + + for_each_queue(bp, i) { + DP(NETIF_MSG_IFDOWN, "about to rlease fp #%d->%d irq " + "state(%x)\n", i, bp->msix_table[i + 1].vector, + bnx2x_fp(bp, i, state)); + + if (bnx2x_fp(bp, i, state) != BNX2X_FP_STATE_CLOSED) { + + free_irq(bp->msix_table[i + 1].vector, &bp->fp[i]); + bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_CLOSED; + + } else + DP(NETIF_MSG_IFDOWN, "irq not freed\n"); + + } + +} + +static void bnx2x_free_irq(struct bnx2x *bp) +{ + + if (bp->flags & USING_MSIX_FLAG) { + + bnx2x_free_msix_irqs(bp); + pci_disable_msix(bp->pdev); + + bp->flags &= ~USING_MSIX_FLAG; + + } else + free_irq(bp->pdev->irq, bp->dev); +} + +static int bnx2x_enable_msix(struct bnx2x *bp) +{ + + int i; + + bp->msix_table[0].entry = 0; + for_each_queue(bp, i) + bp->msix_table[i + 1].entry = i + 1; + + if (pci_enable_msix(bp->pdev, &bp->msix_table[0], + bp->num_queues + 1)){ + BNX2X_ERR("failed to enable msix\n"); + return -1; + + } + + bp->flags |= USING_MSIX_FLAG; + + return 0; + +} + + +static int bnx2x_req_msix_irqs(struct bnx2x *bp) +{ + + + int i, rc; + + DP(NETIF_MSG_IFUP, "about to request sp irq\n"); + + rc = request_irq(bp->msix_table[0].vector, bnx2x_msix_sp_int, 0, + bp->dev->name, bp->dev); + + if (rc) { + BNX2X_ERR("request sp irq failed\n"); + return -EBUSY; + } + + for_each_queue(bp, i) { + rc = request_irq(bp->msix_table[i + 1].vector, + bnx2x_msix_fp_int, 0, + bp->dev->name, &bp->fp[i]); + + if (rc) { + BNX2X_ERR("request fp #%d irq failed\n", i); + bnx2x_free_msix_irqs(bp); + return -EBUSY; + } + + bnx2x_fp(bp, i, state) = BNX2X_FP_STATE_IRQ; + + } + + return 0; + +} + +static int bnx2x_req_irq(struct bnx2x *bp) +{ + + int rc = request_irq(bp->pdev->irq, bnx2x_interrupt, + IRQF_SHARED, bp->dev->name, bp->dev); + if (!rc) + bnx2x_fp(bp, 0, state) = BNX2X_FP_STATE_IRQ; + + return rc; + +} + +/* + * Init service functions + */ + +static void bnx2x_set_mac_addr(struct bnx2x *bp) +{ + struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); + + /* CAM allocation + * unicasts 0-31:port0 32-63:port1 + * multicast 64-127:port0 128-191:port1 + */ + config->hdr.length_6b = 2; + config->hdr.offset = bp->port ? 31 : 0; + config->hdr.reserved0 = 0; + config->hdr.reserved1 = 0; + + /* primary MAC */ + config->config_table[0].cam_entry.msb_mac_addr = + swab16(*(u16 *)&bp->dev->dev_addr[0]); + config->config_table[0].cam_entry.middle_mac_addr = + swab16(*(u16 *)&bp->dev->dev_addr[2]); + config->config_table[0].cam_entry.lsb_mac_addr = + swab16(*(u16 *)&bp->dev->dev_addr[4]); + config->config_table[0].cam_entry.flags = cpu_to_le16(bp->port); + config->config_table[0].target_table_entry.flags = 0; + config->config_table[0].target_table_entry.client_id = 0; + config->config_table[0].target_table_entry.vlan_id = 0; + + DP(NETIF_MSG_IFUP, "setting MAC (%04x:%04x:%04x)\n", + 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 */ + config->config_table[1].cam_entry.msb_mac_addr = 0xffff; + config->config_table[1].cam_entry.middle_mac_addr = 0xffff; + config->config_table[1].cam_entry.lsb_mac_addr = 0xffff; + config->config_table[1].cam_entry.flags = cpu_to_le16(bp->port); + config->config_table[1].target_table_entry.flags = + TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; + config->config_table[1].target_table_entry.client_id = 0; + config->config_table[1].target_table_entry.vlan_id = 0; + + 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); +} + +static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int poll) +{ + /* can take a while if any port is running */ + int timeout = 500; + + /* DP("waiting for state to become %d on IDX [%d]\n", + state, sb_idx); */ + + might_sleep(); + + while (timeout) { + + if (poll) { + bnx2x_rx_int(bp->fp, 10); + /* If index is different from 0 + * The reply for some commands will + * be on the none default queue + */ + if (idx) + bnx2x_rx_int(&bp->fp[idx], 10); + } + + mb(); /* state is changed by bnx2x_sp_event()*/ + + if (*state_p != state) + return 0; + + timeout--; + msleep(1); + + } + + + /* timeout! */ + BNX2X_ERR("timeout waiting for ramrod %d on %d\n", state, idx); + return -EBUSY; + +} + +static int bnx2x_setup_leading(struct bnx2x *bp) +{ + + /* reset IGU staae */ + bnx2x_ack_sb(bp, DEF_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); + + return bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); + +} + +static int bnx2x_setup_multi(struct bnx2x *bp, int index) +{ + + /* reset IGU state */ + bnx2x_ack_sb(bp, index, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + + bp->fp[index].state = BNX2X_FP_STATE_OPENING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, index, 0); + + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, + &(bp->fp[index].state), 1); + +} + + +static int bnx2x_poll(struct napi_struct *napi, int budget); +static void bnx2x_set_rx_mode(struct net_device *dev); + +static int bnx2x_nic_load(struct bnx2x *bp, int req_irq) +{ + int rc; + int i = 0; + + bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; + + /* 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 (!nomcp) { + rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + if (rc == FW_MSG_CODE_DRV_LOAD_REFUSED) { + return -EBUSY; /* other port in diagnostic mode */ + } + } else { + rc = FW_MSG_CODE_DRV_LOAD_COMMON; + } + + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", bp->num_queues); + + /* if we can't use msix we only need one fp, + * so try to enable msix with the requested number of fp's + * and fallback to inta with one fp + */ + if (req_irq) { + + if (use_inta) { + bp->num_queues = 1; + } else { + if (use_multi > 1 && use_multi <= 16) + /* user requested number */ + bp->num_queues = use_multi; + else if (use_multi == 1) + bp->num_queues = num_online_cpus(); + else + bp->num_queues = 1; + + if (bnx2x_enable_msix(bp)) { + /* faild to enable msix */ + bp->num_queues = 1; + if (use_multi) + BNX2X_ERR("Muti requested but failed" + " to enable MSI-X\n"); + } + } + } + + if (bnx2x_alloc_mem(bp)) + return -ENOMEM; + + if (req_irq) { + if (bp->flags & USING_MSIX_FLAG) { + if (bnx2x_req_msix_irqs(bp)) { + pci_disable_msix(bp->pdev); + goto out_error; + } + + } else { + if (bnx2x_req_irq(bp)) { + BNX2X_ERR("IRQ request failed, aborting\n"); + goto out_error; + } + } + } + + for_each_queue(bp, i) + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, 128); + + + /* Initialize HW */ + if (bnx2x_function_init(bp, (rc == FW_MSG_CODE_DRV_LOAD_COMMON))) { + BNX2X_ERR("HW init failed, aborting\n"); + goto out_error; + } + + + atomic_set(&bp->intr_sem, 0); + + /* Reenable SP tasklet */ + /*if (bp->sp_task_en) { */ + /* tasklet_enable(&bp->sp_task);*/ + /*} else { */ + /* bp->sp_task_en = 1; */ + /*} */ + + /* Setup NIC internals and enable interrupts */ + bnx2x_nic_init(bp); + + /* Send LOAD_DONE command to MCP */ + if (!nomcp) { + rc = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + DP(NETIF_MSG_IFUP, "rc = 0x%x\n", rc); + if (!rc) { + BNX2X_ERR("MCP response failure, unloading\n"); + goto int_disable; + } + } + + bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; + + /* Enable Rx interrupt handling before sending the ramrod + as it's completed on Rx FP queue */ + for_each_queue(bp, i) + napi_enable(&bnx2x_fp(bp, i, napi)); + + if (bnx2x_setup_leading(bp)) + goto stop_netif; + + for_each_nondefault_queue(bp, i) + if (bnx2x_setup_multi(bp, i)) + goto stop_netif; + + bnx2x_set_mac_addr(bp); + + bnx2x_phy_init(bp); + + /* Start fast path */ + if (req_irq) { /* IRQ is only requested from bnx2x_open */ + netif_start_queue(bp->dev); + if (bp->flags & USING_MSIX_FLAG) + printk(KERN_INFO PFX "%s: using MSI-X\n", + bp->dev->name); + + /* Otherwise Tx queue should be only reenabled */ + } else if (netif_running(bp->dev)) { + netif_wake_queue(bp->dev); + bnx2x_set_rx_mode(bp->dev); + } + + /* start the timer */ + mod_timer(&bp->timer, jiffies + bp->current_interval); + + return 0; + +stop_netif: + for_each_queue(bp, i) + napi_disable(&bnx2x_fp(bp, i, napi)); + +int_disable: + bnx2x_disable_int_sync(bp); + + bnx2x_free_skbs(bp); + bnx2x_free_irq(bp); + +out_error: + bnx2x_free_mem(bp); + + /* TBD we really need to reset the chip + if we want to recover from this */ + return rc; +} + +static void bnx2x_netif_stop(struct bnx2x *bp) +{ + int i; + + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); + + bnx2x_disable_int_sync(bp); + bnx2x_link_reset(bp); + + for_each_queue(bp, i) + napi_disable(&bnx2x_fp(bp, i, napi)); + + if (netif_running(bp->dev)) { + netif_tx_disable(bp->dev); + bp->dev->trans_start = jiffies; /* prevent tx timeout */ + } +} + +static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) +{ + int port = bp->port; +#ifdef USE_DMAE + u32 wb_write[2]; +#endif + int base, i; + + DP(NETIF_MSG_IFDOWN, "reset called with code %x\n", reset_code); + + /* Do not rcv packets to BRB */ + REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK + port*4, 0x0); + /* Do not direct rcv packets that are not for MCP to the BRB */ + REG_WR(bp, (port ? NIG_REG_LLH1_BRB1_NOT_MCP : + NIG_REG_LLH0_BRB1_NOT_MCP), 0x0); + + /* Configure IGU and AEU */ + REG_WR(bp, HC_REG_CONFIG_0 + port*4, 0x1000); + REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, 0); + + /* TODO: Close Doorbell port? */ + + /* Clear ILT */ +#ifdef USE_DMAE + wb_write[0] = 0; + wb_write[1] = 0; +#endif + base = port * RQ_ONCHIP_AT_PORT_SIZE; + for (i = base; i < base + RQ_ONCHIP_AT_PORT_SIZE; i++) { +#ifdef USE_DMAE + REG_WR_DMAE(bp, PXP2_REG_RQ_ONCHIP_AT + i*8, wb_write, 2); +#else + REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT, 0); + REG_WR_IND(bp, PXP2_REG_RQ_ONCHIP_AT + 4, 0); +#endif + } + + if (reset_code == FW_MSG_CODE_DRV_UNLOAD_COMMON) { + /* reset_common */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, + 0xd3ffff7f); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + 0x1403); + } +} + +static int bnx2x_stop_multi(struct bnx2x *bp, int index) +{ + + int rc; + + /* halt the connnection */ + bp->fp[index].state = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, 0, 0); + + + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, + &(bp->fp[index].state), 1); + if (rc) /* timout */ + return rc; + + /* delete cfc entry */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + + return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_DELETED, index, + &(bp->fp[index].state), 1); + +} + + +static void bnx2x_stop_leading(struct bnx2x *bp) +{ + + /* if the other port is hadling traffic, + this can take a lot of time */ + int timeout = 500; + + might_sleep(); + + /* Send HALT ramrod */ + bp->fp[0].state = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, 0, 0); + + if (bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, + &(bp->fp[0].state), 1)) + return; + + bp->dsb_sp_prod_idx = *bp->dsb_sp_prod; + + /* Send CFC_DELETE ramrod */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); + + /* + Wait for completion. + we are going to reset the chip anyway + so there is not much to do if this times out + */ + while (bp->dsb_sp_prod_idx == *bp->dsb_sp_prod && timeout) { + timeout--; + msleep(1); + } + +} + +static int bnx2x_nic_unload(struct bnx2x *bp, int fre_irq) +{ + u32 reset_code = 0; + int rc; + int i; + + bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; + + /* Calling flush_scheduled_work() may deadlock because + * linkwatch_event() may be on the workqueue and it will try to get + * the rtnl_lock which we are holding. + */ + + while (bp->in_reset_task) + msleep(1); + + /* Delete the timer: do it before disabling interrupts, as it + may be stil STAT_QUERY ramrod pending after stopping the timer */ + del_timer_sync(&bp->timer); + + /* Wait until stat ramrod returns and all SP tasks complete */ + while (bp->stat_pending && (bp->spq_left != MAX_SPQ_PENDING)) + msleep(1); + + /* Stop fast path, disable MAC, disable interrupts, disable napi */ + bnx2x_netif_stop(bp); + + if (bp->flags & NO_WOL_FLAG) + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP; + else if (bp->wol) { + u32 emac_base = bp->port ? GRCBASE_EMAC0 : GRCBASE_EMAC1; + u8 *mac_addr = bp->dev->dev_addr; + u32 val = (EMAC_MODE_MPKT | EMAC_MODE_MPKT_RCVD | + EMAC_MODE_ACPI_RCVD); + + EMAC_WR(EMAC_REG_EMAC_MODE, val); + + val = (mac_addr[0] << 8) | mac_addr[1]; + EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val); + + val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | + (mac_addr[4] << 8) | mac_addr[5]; + EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); + + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN; + } else + reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; + + for_each_nondefault_queue(bp, i) + if (bnx2x_stop_multi(bp, i)) + goto error; + + + bnx2x_stop_leading(bp); + +error: + if (!nomcp) + rc = bnx2x_fw_command(bp, reset_code); + else + rc = FW_MSG_CODE_DRV_UNLOAD_COMMON; + + /* Release IRQs */ + if (fre_irq) + bnx2x_free_irq(bp); + + /* Reset the chip */ + bnx2x_reset_chip(bp, rc); + + /* Report UNLOAD_DONE to MCP */ + if (!nomcp) + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + + /* Free SKBs and driver internals */ + bnx2x_free_skbs(bp); + bnx2x_free_mem(bp); + + bp->state = BNX2X_STATE_CLOSED; + /* Set link down */ + bp->link_up = 0; + netif_carrier_off(bp->dev); + + return 0; +} + +/* end of nic load/unload */ + +/* ethtool_ops */ + +/* + * Init service functions + */ + +static void bnx2x_link_settings_supported(struct bnx2x *bp, u32 switch_cfg) +{ + int port = bp->port; + u32 ext_phy_type; + + bp->phy_flags = 0; + + 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); + 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->supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseT_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->phy_flags |= PHY_SGMII_FLAG; + + bp->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->ext_phy_config); + return; + } + + bp->phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + + port*0x10); + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr); + break; + + case SWITCH_CFG_10G: + BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg); + + bp->phy_flags |= PHY_XGXS_FLAG; + + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + 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->supported |= (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + BNX2X_DEV_INFO("ext_phy_type 0x%x (8705/6)\n", + ext_phy_type); + + bp->supported |= (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause); + break; + + default: + BNX2X_ERR("NVRAM config error. " + "BAD XGXS ext_phy_config 0x%x\n", + bp->ext_phy_config); + return; + } + + bp->phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + + port*0x18); + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->phy_addr); + + bp->ser_lane = ((bp->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + bp->rx_lane_swap = ((bp->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT); + bp->tx_lane_swap = ((bp->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); + BNX2X_DEV_INFO("rx_lane_swap 0x%x tx_lane_swap 0x%x\n", + bp->rx_lane_swap, bp->tx_lane_swap); + break; + + default: + BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", + bp->link_config); + return; + } + + /* mask what we support according to speed_cap_mask */ + if (!(bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) + bp->supported &= ~SUPPORTED_10baseT_Half; + + if (!(bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) + bp->supported &= ~SUPPORTED_10baseT_Full; + + if (!(bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) + bp->supported &= ~SUPPORTED_100baseT_Half; + + if (!(bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) + bp->supported &= ~SUPPORTED_100baseT_Full; + + if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) + bp->supported &= ~(SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); + + if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) + bp->supported &= ~SUPPORTED_2500baseT_Full; + + if (!(bp->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) + bp->supported &= ~SUPPORTED_10000baseT_Full; + + BNX2X_DEV_INFO("supported 0x%x\n", bp->supported); +} + +static void bnx2x_link_settings_requested(struct bnx2x *bp) +{ + bp->req_autoneg = 0; + bp->req_duplex = DUPLEX_FULL; + + switch (bp->link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_AUTO: + if (bp->supported & SUPPORTED_Autoneg) { + bp->req_autoneg |= AUTONEG_SPEED; + bp->req_line_speed = 0; + bp->advertising = bp->supported; + } else { + u32 ext_phy_type; + + ext_phy_type = XGXS_EXT_PHY_TYPE(bp); + 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->req_line_speed = SPEED_10000; + bp->advertising = + (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + break; + } + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " Autoneg not supported\n", + bp->link_config); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_10M_FULL: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) { + bp->req_line_speed = SPEED_10; + bp->advertising = (ADVERTISED_10baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_10M_HALF: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF) { + bp->req_line_speed = SPEED_10; + bp->req_duplex = DUPLEX_HALF; + bp->advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_100M_FULL: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL) { + bp->req_line_speed = SPEED_100; + bp->advertising = (ADVERTISED_100baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_100M_HALF: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF) { + bp->req_line_speed = SPEED_100; + bp->req_duplex = DUPLEX_HALF; + bp->advertising = (ADVERTISED_100baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_1G: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { + bp->req_line_speed = SPEED_1000; + bp->advertising = (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_2_5G: + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) { + bp->req_line_speed = SPEED_2500; + bp->advertising = (ADVERTISED_2500baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + case PORT_FEATURE_LINK_SPEED_10G_CX4: + case PORT_FEATURE_LINK_SPEED_10G_KX4: + case PORT_FEATURE_LINK_SPEED_10G_KR: + if (!(bp->phy_flags & PHY_XGXS_FLAG)) { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " phy_flags 0x%x\n", + bp->link_config, bp->phy_flags); + return; + } + if (bp->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { + bp->req_line_speed = SPEED_10000; + bp->advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + } else { + BNX2X_ERR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + bp->link_config, bp->speed_cap_mask); + return; + } + break; + + default: + BNX2X_ERR("NVRAM config error. " + "BAD link speed link_config 0x%x\n", + bp->link_config); + bp->req_autoneg |= AUTONEG_SPEED; + bp->req_line_speed = 0; + bp->advertising = bp->supported; + break; + } + BNX2X_DEV_INFO("req_line_speed %d req_duplex %d\n", + bp->req_line_speed, bp->req_duplex); + + bp->req_flow_ctrl = (bp->link_config & + PORT_FEATURE_FLOW_CONTROL_MASK); + /* Please refer to Table 28B-3 of the 802.3ab-1999 spec */ + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + bp->req_autoneg |= AUTONEG_FLOW_CTRL; + if (bp->dev->mtu <= 4500) { + bp->pause_mode = PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + bp->pause_mode = PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + break; + + case FLOW_CTRL_TX: + bp->pause_mode = PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + bp->pause_mode = PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + + case FLOW_CTRL_NONE: + default: + bp->pause_mode = PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } + BNX2X_DEV_INFO("req_autoneg 0x%x req_flow_ctrl 0x%x\n" + KERN_INFO " pause_mode %d advertising 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl, + bp->pause_mode, bp->advertising); +} + +static void bnx2x_get_hwinfo(struct bnx2x *bp) +{ + u32 val, val2, val3, val4, id; + int port = bp->port; + u32 switch_cfg; + + bp->shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); + BNX2X_DEV_INFO("shmem offset is %x\n", bp->shmem_base); + + /* Get the chip revision id and number. */ + /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ + val = REG_RD(bp, MISC_REG_CHIP_NUM); + id = ((val & 0xffff) << 16); + val = REG_RD(bp, MISC_REG_CHIP_REV); + id |= ((val & 0xf) << 12); + val = REG_RD(bp, MISC_REG_CHIP_METAL); + id |= ((val & 0xff) << 4); + REG_RD(bp, MISC_REG_BOND_ID); + id |= (val & 0xf); + bp->chip_id = id; + BNX2X_DEV_INFO("chip ID is %x\n", id); + + if (!bp->shmem_base || (bp->shmem_base != 0xAF900)) { + BNX2X_DEV_INFO("MCP not active\n"); + nomcp = 1; + goto set_mac; + } + + val = SHMEM_RD(bp, validity_map[port]); + if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) + BNX2X_ERR("MCP validity signature bad\n"); + + bp->fw_seq = (SHMEM_RD(bp, drv_fw_mb[port].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + + bp->hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); + + bp->serdes_config = + SHMEM_RD(bp, dev_info.port_hw_config[bp->port].serdes_config); + bp->lane_config = + SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); + bp->ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + bp->speed_cap_mask = + SHMEM_RD(bp, + dev_info.port_hw_config[port].speed_capability_mask); + + bp->link_config = + SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); + + BNX2X_DEV_INFO("hw_config (%08x) serdes_config (%08x)\n" + KERN_INFO " lane_config (%08x) ext_phy_config (%08x)\n" + KERN_INFO " speed_cap_mask (%08x) link_config (%08x)" + " fw_seq (%08x)\n", + bp->hw_config, bp->serdes_config, bp->lane_config, + bp->ext_phy_config, bp->speed_cap_mask, + bp->link_config, bp->fw_seq); + + switch_cfg = (bp->link_config & PORT_FEATURE_CONNECTED_SWITCH_MASK); + bnx2x_link_settings_supported(bp, switch_cfg); + + bp->autoneg = (bp->hw_config & SHARED_HW_CFG_AN_ENABLE_MASK); + /* for now disable cl73 */ + bp->autoneg &= ~SHARED_HW_CFG_AN_ENABLE_CL73; + BNX2X_DEV_INFO("autoneg 0x%x\n", bp->autoneg); + + bnx2x_link_settings_requested(bp); + + val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); + val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); + bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); + bp->dev->dev_addr[1] = (u8)(val2 & 0xff); + bp->dev->dev_addr[2] = (u8)(val >> 24 & 0xff); + bp->dev->dev_addr[3] = (u8)(val >> 16 & 0xff); + bp->dev->dev_addr[4] = (u8)(val >> 8 & 0xff); + bp->dev->dev_addr[5] = (u8)(val & 0xff); + + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6); + + + val = SHMEM_RD(bp, dev_info.shared_hw_config.part_num); + val2 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[4]); + val3 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[8]); + val4 = SHMEM_RD(bp, dev_info.shared_hw_config.part_num[12]); + + printk(KERN_INFO PFX "part number %X-%X-%X-%X\n", + val, val2, val3, val4); + + /* bc ver */ + if (!nomcp) { + bp->bc_ver = val = ((SHMEM_RD(bp, dev_info.bc_rev)) >> 8); + BNX2X_DEV_INFO("bc_ver %X\n", val); + if (val < BNX2X_BC_VER) { + /* for now only warn + * later we might need to enforce this */ + BNX2X_ERR("This driver needs bc_ver %X but found %X," + " please upgrade BC\n", BNX2X_BC_VER, val); + } + } else { + bp->bc_ver = 0; + } + + val = REG_RD(bp, MCP_REG_MCPR_NVM_CFG4); + bp->flash_size = (NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE)); + BNX2X_DEV_INFO("flash_size 0x%x (%d)\n", + bp->flash_size, bp->flash_size); + + return; + +set_mac: /* only supposed to happen on emulation/FPGA */ + BNX2X_ERR("warning constant MAC workaround active\n"); + bp->dev->dev_addr[0] = 0; + bp->dev->dev_addr[1] = 0x50; + bp->dev->dev_addr[2] = 0xc2; + bp->dev->dev_addr[3] = 0x2c; + bp->dev->dev_addr[4] = 0x71; + bp->dev->dev_addr[5] = port ? 0x0d : 0x0e; + + memcpy(bp->dev->perm_addr, bp->dev->dev_addr, 6); + +} + +/* + * ethtool service functions + */ + +/* All ethtool functions called with rtnl_lock */ + +static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct bnx2x *bp = netdev_priv(dev); + + cmd->supported = bp->supported; + cmd->advertising = bp->advertising; + + if (netif_carrier_ok(dev)) { + cmd->speed = bp->line_speed; + cmd->duplex = bp->duplex; + } else { + cmd->speed = bp->req_line_speed; + cmd->duplex = bp->req_duplex; + } + + if (bp->phy_flags & PHY_XGXS_FLAG) { + cmd->port = PORT_FIBRE; + } else { + cmd->port = PORT_TP; + } + + cmd->phy_address = bp->phy_addr; + cmd->transceiver = XCVR_INTERNAL; + + if (bp->req_autoneg & AUTONEG_SPEED) { + cmd->autoneg = AUTONEG_ENABLE; + } else { + cmd->autoneg = AUTONEG_DISABLE; + } + + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + + DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" + DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" + DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" + DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, + cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + + return 0; +} + +static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 advertising; + + DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" + DP_LEVEL " supported 0x%x advertising 0x%x speed %d\n" + DP_LEVEL " duplex %d port %d phy_address %d transceiver %d\n" + DP_LEVEL " autoneg %d maxtxpkt %d maxrxpkt %d\n", + cmd->cmd, cmd->supported, cmd->advertising, cmd->speed, + cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, + cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + + switch (cmd->port) { + case PORT_TP: + if (!(bp->supported & SUPPORTED_TP)) + return -EINVAL; + + if (bp->phy_flags & PHY_XGXS_FLAG) { + bnx2x_link_reset(bp); + bnx2x_link_settings_supported(bp, SWITCH_CFG_1G); + bnx2x_phy_deassert(bp); + } + break; + + case PORT_FIBRE: + if (!(bp->supported & SUPPORTED_FIBRE)) + return -EINVAL; + + if (!(bp->phy_flags & PHY_XGXS_FLAG)) { + bnx2x_link_reset(bp); + bnx2x_link_settings_supported(bp, SWITCH_CFG_10G); + bnx2x_phy_deassert(bp); + } + break; + + default: + return -EINVAL; + } + + if (cmd->autoneg == AUTONEG_ENABLE) { + if (!(bp->supported & SUPPORTED_Autoneg)) + return -EINVAL; + + /* advertise the requested speed and duplex if supported */ + cmd->advertising &= bp->supported; + + bp->req_autoneg |= AUTONEG_SPEED; + bp->req_line_speed = 0; + bp->req_duplex = DUPLEX_FULL; + bp->advertising |= (ADVERTISED_Autoneg | cmd->advertising); + + } else { /* forced speed */ + /* advertise the requested speed and duplex if supported */ + switch (cmd->speed) { + case SPEED_10: + if (cmd->duplex == DUPLEX_FULL) { + if (!(bp->supported & SUPPORTED_10baseT_Full)) + return -EINVAL; + + advertising = (ADVERTISED_10baseT_Full | + ADVERTISED_TP); + } else { + if (!(bp->supported & SUPPORTED_10baseT_Half)) + return -EINVAL; + + advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_TP); + } + break; + + case SPEED_100: + if (cmd->duplex == DUPLEX_FULL) { + if (!(bp->supported & + SUPPORTED_100baseT_Full)) + return -EINVAL; + + advertising = (ADVERTISED_100baseT_Full | + ADVERTISED_TP); + } else { + if (!(bp->supported & + SUPPORTED_100baseT_Half)) + return -EINVAL; + + advertising = (ADVERTISED_100baseT_Half | + ADVERTISED_TP); + } + break; + + case SPEED_1000: + if (cmd->duplex != DUPLEX_FULL) + return -EINVAL; + + if (!(bp->supported & SUPPORTED_1000baseT_Full)) + return -EINVAL; + + advertising = (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + break; + + case SPEED_2500: + if (cmd->duplex != DUPLEX_FULL) + return -EINVAL; + + if (!(bp->supported & SUPPORTED_2500baseT_Full)) + return -EINVAL; + + advertising = (ADVERTISED_2500baseT_Full | + ADVERTISED_TP); + break; + + case SPEED_10000: + if (cmd->duplex != DUPLEX_FULL) + return -EINVAL; + + if (!(bp->supported & SUPPORTED_10000baseT_Full)) + return -EINVAL; + + advertising = (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + break; + + default: + return -EINVAL; + } + + bp->req_autoneg &= ~AUTONEG_SPEED; + bp->req_line_speed = cmd->speed; + bp->req_duplex = cmd->duplex; + bp->advertising = advertising; + } + + DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_line_speed %d\n" + DP_LEVEL " req_duplex %d advertising 0x%x\n", + bp->req_autoneg, bp->req_line_speed, bp->req_duplex, + bp->advertising); + + bnx2x_stop_stats(bp); + bnx2x_link_initialize(bp); + + return 0; +} + +static void bnx2x_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct bnx2x *bp = netdev_priv(dev); + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + snprintf(info->fw_version, 32, "%d.%d.%d:%d (BC VER %x)", + BCM_5710_FW_MAJOR_VERSION, BCM_5710_FW_MINOR_VERSION, + BCM_5710_FW_REVISION_VERSION, BCM_5710_FW_COMPILE_FLAGS, + bp->bc_ver); + strcpy(info->bus_info, pci_name(bp->pdev)); + info->n_stats = BNX2X_NUM_STATS; + info->testinfo_len = BNX2X_NUM_TESTS; + info->eedump_len = bp->flash_size; + info->regdump_len = 0; +} + +static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (bp->flags & NO_WOL_FLAG) { + wol->supported = 0; + wol->wolopts = 0; + } else { + wol->supported = WAKE_MAGIC; + if (bp->wol) + wol->wolopts = WAKE_MAGIC; + else + wol->wolopts = 0; + } + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int bnx2x_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (wol->wolopts & ~WAKE_MAGIC) + return -EINVAL; + + if (wol->wolopts & WAKE_MAGIC) { + if (bp->flags & NO_WOL_FLAG) + return -EINVAL; + + bp->wol = 1; + } else { + bp->wol = 0; + } + return 0; +} + +static u32 bnx2x_get_msglevel(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + return bp->msglevel; +} + +static void bnx2x_set_msglevel(struct net_device *dev, u32 level) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (capable(CAP_NET_ADMIN)) + bp->msglevel = level; +} + +static int bnx2x_nway_reset(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + if (bp->state != BNX2X_STATE_OPEN) { + DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state); + return -EAGAIN; + } + + bnx2x_stop_stats(bp); + bnx2x_link_initialize(bp); + + return 0; +} + +static int bnx2x_get_eeprom_len(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + return bp->flash_size; +} + +static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) +{ + int port = bp->port; + int count, i; + u32 val = 0; + + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* request access to nvram interface */ + REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, + (MCPR_NVM_SW_ARB_ARB_REQ_SET1 << port)); + + for (i = 0; i < count*10; i++) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); + if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) + break; + + udelay(5); + } + + if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) { + DP(NETIF_MSG_NVM, "cannot get access to nvram interface\n"); + return -EBUSY; + } + + return 0; +} + +static int bnx2x_release_nvram_lock(struct bnx2x *bp) +{ + int port = bp->port; + int count, i; + u32 val = 0; + + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* relinquish nvram interface */ + REG_WR(bp, MCP_REG_MCPR_NVM_SW_ARB, + (MCPR_NVM_SW_ARB_ARB_REQ_CLR1 << port)); + + for (i = 0; i < count*10; i++) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_SW_ARB); + if (!(val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port))) + break; + + udelay(5); + } + + if (val & (MCPR_NVM_SW_ARB_ARB_ARB1 << port)) { + DP(NETIF_MSG_NVM, "cannot free access to nvram interface\n"); + return -EBUSY; + } + + return 0; +} + +static void bnx2x_enable_nvram_access(struct bnx2x *bp) +{ + u32 val; + + val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); + + /* enable both bits, even on read */ + REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, + (val | MCPR_NVM_ACCESS_ENABLE_EN | + MCPR_NVM_ACCESS_ENABLE_WR_EN)); +} + +static void bnx2x_disable_nvram_access(struct bnx2x *bp) +{ + u32 val; + + val = REG_RD(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE); + + /* disable both bits, even after read */ + REG_WR(bp, MCP_REG_MCPR_NVM_ACCESS_ENABLE, + (val & ~(MCPR_NVM_ACCESS_ENABLE_EN | + MCPR_NVM_ACCESS_ENABLE_WR_EN))); +} + +static int bnx2x_nvram_read_dword(struct bnx2x *bp, u32 offset, u32 *ret_val, + u32 cmd_flags) +{ + int rc; + int count, i; + u32 val; + + /* build the command word */ + cmd_flags |= MCPR_NVM_COMMAND_DOIT; + + /* need to clear DONE bit separately */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); + + /* address of the NVRAM to read from */ + REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, + (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); + + /* issue a read command */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); + + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* wait for completion */ + *ret_val = 0; + rc = -EBUSY; + for (i = 0; i < count; i++) { + udelay(5); + val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); + + if (val & MCPR_NVM_COMMAND_DONE) { + val = REG_RD(bp, MCP_REG_MCPR_NVM_READ); + DP(NETIF_MSG_NVM, "val 0x%08x\n", val); + /* we read nvram data in cpu order + * but ethtool sees it as an array of bytes + * converting to big-endian will do the work */ + val = cpu_to_be32(val); + *ret_val = val; + rc = 0; + break; + } + } + + return rc; +} + +static int bnx2x_nvram_read(struct bnx2x *bp, u32 offset, u8 *ret_buf, + int buf_size) +{ + int rc; + u32 cmd_flags; + u32 val; + + if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { + DP(NETIF_MSG_NVM, + "Invalid paramter: offset 0x%x buf_size 0x%x\n", + offset, buf_size); + return -EINVAL; + } + + if (offset + buf_size > bp->flash_size) { + DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->flash_size); + return -EINVAL; + } + + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; + + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); + + /* read the first word(s) */ + cmd_flags = MCPR_NVM_COMMAND_FIRST; + while ((buf_size > sizeof(u32)) && (rc == 0)) { + rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); + memcpy(ret_buf, &val, 4); + + /* advance to the next dword */ + offset += sizeof(u32); + ret_buf += sizeof(u32); + buf_size -= sizeof(u32); + cmd_flags = 0; + } + + if (rc == 0) { + cmd_flags |= MCPR_NVM_COMMAND_LAST; + rc = bnx2x_nvram_read_dword(bp, offset, &val, cmd_flags); + memcpy(ret_buf, &val, 4); + } + + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); + + return rc; +} + +static int bnx2x_get_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *eebuf) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc; + + DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n" + DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", + eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, + eeprom->len, eeprom->len); + + /* parameters already validated in ethtool_get_eeprom */ + + rc = bnx2x_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); + + return rc; +} + +static int bnx2x_nvram_write_dword(struct bnx2x *bp, u32 offset, u32 val, + u32 cmd_flags) +{ + int rc; + int count, i; + + /* build the command word */ + cmd_flags |= MCPR_NVM_COMMAND_DOIT | MCPR_NVM_COMMAND_WR; + + /* need to clear DONE bit separately */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, MCPR_NVM_COMMAND_DONE); + + /* write the data */ + REG_WR(bp, MCP_REG_MCPR_NVM_WRITE, val); + + /* address of the NVRAM to write to */ + REG_WR(bp, MCP_REG_MCPR_NVM_ADDR, + (offset & MCPR_NVM_ADDR_NVM_ADDR_VALUE)); + + /* issue the write command */ + REG_WR(bp, MCP_REG_MCPR_NVM_COMMAND, cmd_flags); + + /* adjust timeout for emulation/FPGA */ + count = NVRAM_TIMEOUT_COUNT; + if (CHIP_REV_IS_SLOW(bp)) + count *= 100; + + /* wait for completion */ + rc = -EBUSY; + for (i = 0; i < count; i++) { + udelay(5); + val = REG_RD(bp, MCP_REG_MCPR_NVM_COMMAND); + if (val & MCPR_NVM_COMMAND_DONE) { + rc = 0; + break; + } + } + + return rc; +} + +#define BYTE_OFFSET(offset) (8 * (offset & 0x03)) + +static int bnx2x_nvram_write1(struct bnx2x *bp, u32 offset, u8 *data_buf, + int buf_size) +{ + int rc; + u32 cmd_flags; + u32 align_offset; + u32 val; + + if (offset + buf_size > bp->flash_size) { + DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->flash_size); + return -EINVAL; + } + + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; + + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); + + cmd_flags = (MCPR_NVM_COMMAND_FIRST | MCPR_NVM_COMMAND_LAST); + align_offset = (offset & ~0x03); + rc = bnx2x_nvram_read_dword(bp, align_offset, &val, cmd_flags); + + if (rc == 0) { + val &= ~(0xff << BYTE_OFFSET(offset)); + val |= (*data_buf << BYTE_OFFSET(offset)); + + /* nvram data is returned as an array of bytes + * convert it back to cpu order */ + val = be32_to_cpu(val); + + DP(NETIF_MSG_NVM, "val 0x%08x\n", val); + + rc = bnx2x_nvram_write_dword(bp, align_offset, val, + cmd_flags); + } + + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); + + return rc; +} + +static int bnx2x_nvram_write(struct bnx2x *bp, u32 offset, u8 *data_buf, + int buf_size) +{ + int rc; + u32 cmd_flags; + u32 val; + u32 written_so_far; + + if (buf_size == 1) { /* ethtool */ + return bnx2x_nvram_write1(bp, offset, data_buf, buf_size); + } + + if ((offset & 0x03) || (buf_size & 0x03) || (buf_size == 0)) { + DP(NETIF_MSG_NVM, + "Invalid paramter: offset 0x%x buf_size 0x%x\n", + offset, buf_size); + return -EINVAL; + } + + if (offset + buf_size > bp->flash_size) { + DP(NETIF_MSG_NVM, "Invalid paramter: offset (0x%x) +" + " buf_size (0x%x) > flash_size (0x%x)\n", + offset, buf_size, bp->flash_size); + return -EINVAL; + } + + /* request access to nvram interface */ + rc = bnx2x_acquire_nvram_lock(bp); + if (rc) + return rc; + + /* enable access to nvram interface */ + bnx2x_enable_nvram_access(bp); + + written_so_far = 0; + cmd_flags = MCPR_NVM_COMMAND_FIRST; + while ((written_so_far < buf_size) && (rc == 0)) { + if (written_so_far == (buf_size - sizeof(u32))) + cmd_flags |= MCPR_NVM_COMMAND_LAST; + else if (((offset + 4) % NVRAM_PAGE_SIZE) == 0) + cmd_flags |= MCPR_NVM_COMMAND_LAST; + else if ((offset % NVRAM_PAGE_SIZE) == 0) + cmd_flags |= MCPR_NVM_COMMAND_FIRST; + + memcpy(&val, data_buf, 4); + DP(NETIF_MSG_NVM, "val 0x%08x\n", val); + + rc = bnx2x_nvram_write_dword(bp, offset, val, cmd_flags); + + /* advance to the next dword */ + offset += sizeof(u32); + data_buf += sizeof(u32); + written_so_far += sizeof(u32); + cmd_flags = 0; + } + + /* disable access to nvram interface */ + bnx2x_disable_nvram_access(bp); + bnx2x_release_nvram_lock(bp); + + return rc; +} + +static int bnx2x_set_eeprom(struct net_device *dev, + struct ethtool_eeprom *eeprom, u8 *eebuf) +{ + struct bnx2x *bp = netdev_priv(dev); + int rc; + + DP(NETIF_MSG_NVM, "ethtool_eeprom: cmd %d\n" + DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", + eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, + eeprom->len, eeprom->len); + + /* parameters already validated in ethtool_set_eeprom */ + + rc = bnx2x_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); + + return rc; +} + +static int bnx2x_get_coalesce(struct net_device *dev, + struct ethtool_coalesce *coal) +{ + struct bnx2x *bp = netdev_priv(dev); + + memset(coal, 0, sizeof(struct ethtool_coalesce)); + + coal->rx_coalesce_usecs = bp->rx_ticks; + coal->tx_coalesce_usecs = bp->tx_ticks; + coal->stats_block_coalesce_usecs = bp->stats_ticks; + + return 0; +} + +static int bnx2x_set_coalesce(struct net_device *dev, + struct ethtool_coalesce *coal) +{ + struct bnx2x *bp = netdev_priv(dev); + + bp->rx_ticks = (u16) coal->rx_coalesce_usecs; + if (bp->rx_ticks > 3000) + bp->rx_ticks = 3000; + + bp->tx_ticks = (u16) coal->tx_coalesce_usecs; + if (bp->tx_ticks > 0x3000) + bp->tx_ticks = 0x3000; + + bp->stats_ticks = coal->stats_block_coalesce_usecs; + if (bp->stats_ticks > 0xffff00) + bp->stats_ticks = 0xffff00; + bp->stats_ticks &= 0xffff00; + + if (netif_running(bp->dev)) + bnx2x_update_coalesce(bp); + + return 0; +} + +static void bnx2x_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct bnx2x *bp = netdev_priv(dev); + + ering->rx_max_pending = MAX_RX_AVAIL; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = 0; + + ering->rx_pending = bp->rx_ring_size; + ering->rx_mini_pending = 0; + ering->rx_jumbo_pending = 0; + + ering->tx_max_pending = MAX_TX_AVAIL; + ering->tx_pending = bp->tx_ring_size; +} + +static int bnx2x_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ering) +{ + struct bnx2x *bp = netdev_priv(dev); + + if ((ering->rx_pending > MAX_RX_AVAIL) || + (ering->tx_pending > MAX_TX_AVAIL) || + (ering->tx_pending <= MAX_SKB_FRAGS + 4)) + return -EINVAL; + + bp->rx_ring_size = ering->rx_pending; + bp->tx_ring_size = ering->tx_pending; + + if (netif_running(bp->dev)) { + bnx2x_nic_unload(bp, 0); + bnx2x_nic_load(bp, 0); + } + + return 0; +} + +static void bnx2x_get_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) +{ + struct bnx2x *bp = netdev_priv(dev); + + epause->autoneg = + ((bp->req_autoneg & AUTONEG_FLOW_CTRL) == AUTONEG_FLOW_CTRL); + epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) == FLOW_CTRL_RX); + epause->tx_pause = ((bp->flow_ctrl & FLOW_CTRL_TX) == FLOW_CTRL_TX); + + 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); +} + +static int bnx2x_set_pauseparam(struct net_device *dev, + struct ethtool_pauseparam *epause) +{ + struct bnx2x *bp = netdev_priv(dev); + + 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->req_flow_ctrl = FLOW_CTRL_AUTO; + if (epause->autoneg) { + bp->req_autoneg |= AUTONEG_FLOW_CTRL; + if (bp->dev->mtu <= 4500) { + bp->pause_mode = PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + } else { + bp->pause_mode = PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + } + + } else { + bp->req_autoneg &= ~AUTONEG_FLOW_CTRL; + + if (epause->rx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_RX; + if (epause->tx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_TX; + + switch (bp->req_flow_ctrl) { + case FLOW_CTRL_AUTO: + bp->req_flow_ctrl = FLOW_CTRL_NONE; + bp->pause_mode = PAUSE_NONE; + bp->advertising &= ~(ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + + case FLOW_CTRL_TX: + bp->pause_mode = PAUSE_ASYMMETRIC; + bp->advertising |= ADVERTISED_Asym_Pause; + break; + + case FLOW_CTRL_RX: + case FLOW_CTRL_BOTH: + bp->pause_mode = PAUSE_BOTH; + bp->advertising |= (ADVERTISED_Pause | + ADVERTISED_Asym_Pause); + break; + } + } + + DP(NETIF_MSG_LINK, "req_autoneg 0x%x req_flow_ctrl 0x%x\n" + DP_LEVEL " pause_mode %d advertising 0x%x\n", + bp->req_autoneg, bp->req_flow_ctrl, bp->pause_mode, + bp->advertising); + + bnx2x_stop_stats(bp); + bnx2x_link_initialize(bp); + + return 0; +} + +static u32 bnx2x_get_rx_csum(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + return bp->rx_csum; +} + +static int bnx2x_set_rx_csum(struct net_device *dev, u32 data) +{ + struct bnx2x *bp = netdev_priv(dev); + + bp->rx_csum = data; + return 0; +} + +static int bnx2x_set_tso(struct net_device *dev, u32 data) +{ + if (data) + dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); + else + dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN); + return 0; +} + +static struct { + char string[ETH_GSTRING_LEN]; +} bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = { + { "MC Errors (online)" } +}; + +static int bnx2x_self_test_count(struct net_device *dev) +{ + return BNX2X_NUM_TESTS; +} + +static void bnx2x_self_test(struct net_device *dev, + struct ethtool_test *etest, u64 *buf) +{ + struct bnx2x *bp = netdev_priv(dev); + int stats_state; + + memset(buf, 0, sizeof(u64) * BNX2X_NUM_TESTS); + + if (bp->state != BNX2X_STATE_OPEN) { + DP(NETIF_MSG_PROBE, "state is %x, returning\n", bp->state); + return; + } + + stats_state = bp->stats_state; + bnx2x_stop_stats(bp); + + if (bnx2x_mc_assert(bp) != 0) { + buf[0] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + +#ifdef BNX2X_EXTRA_DEBUG + bnx2x_panic_dump(bp); +#endif + bp->stats_state = stats_state; +} + +static struct { + char string[ETH_GSTRING_LEN]; +} bnx2x_stats_str_arr[BNX2X_NUM_STATS] = { + { "rx_bytes"}, /* 0 */ + { "rx_error_bytes"}, /* 1 */ + { "tx_bytes"}, /* 2 */ + { "tx_error_bytes"}, /* 3 */ + { "rx_ucast_packets"}, /* 4 */ + { "rx_mcast_packets"}, /* 5 */ + { "rx_bcast_packets"}, /* 6 */ + { "tx_ucast_packets"}, /* 7 */ + { "tx_mcast_packets"}, /* 8 */ + { "tx_bcast_packets"}, /* 9 */ + { "tx_mac_errors"}, /* 10 */ + { "tx_carrier_errors"}, /* 11 */ + { "rx_crc_errors"}, /* 12 */ + { "rx_align_errors"}, /* 13 */ + { "tx_single_collisions"}, /* 14 */ + { "tx_multi_collisions"}, /* 15 */ + { "tx_deferred"}, /* 16 */ + { "tx_excess_collisions"}, /* 17 */ + { "tx_late_collisions"}, /* 18 */ + { "tx_total_collisions"}, /* 19 */ + { "rx_fragments"}, /* 20 */ + { "rx_jabbers"}, /* 21 */ + { "rx_undersize_packets"}, /* 22 */ + { "rx_oversize_packets"}, /* 23 */ + { "rx_xon_frames"}, /* 24 */ + { "rx_xoff_frames"}, /* 25 */ + { "tx_xon_frames"}, /* 26 */ + { "tx_xoff_frames"}, /* 27 */ + { "rx_mac_ctrl_frames"}, /* 28 */ + { "rx_filtered_packets"}, /* 29 */ + { "rx_discards"}, /* 30 */ +}; + +#define STATS_OFFSET32(offset_name) \ + (offsetof(struct bnx2x_eth_stats, offset_name) / 4) + +static unsigned long bnx2x_stats_offset_arr[BNX2X_NUM_STATS] = { + STATS_OFFSET32(total_bytes_received_hi), /* 0 */ + STATS_OFFSET32(stat_IfHCInBadOctets_hi), /* 1 */ + STATS_OFFSET32(total_bytes_transmitted_hi), /* 2 */ + STATS_OFFSET32(stat_IfHCOutBadOctets_hi), /* 3 */ + STATS_OFFSET32(total_unicast_packets_received_hi), /* 4 */ + STATS_OFFSET32(total_multicast_packets_received_hi), /* 5 */ + STATS_OFFSET32(total_broadcast_packets_received_hi), /* 6 */ + STATS_OFFSET32(total_unicast_packets_transmitted_hi), /* 7 */ + STATS_OFFSET32(total_multicast_packets_transmitted_hi), /* 8 */ + STATS_OFFSET32(total_broadcast_packets_transmitted_hi), /* 9 */ + STATS_OFFSET32(stat_Dot3statsInternalMacTransmitErrors), /* 10 */ + STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), /* 11 */ + STATS_OFFSET32(crc_receive_errors), /* 12 */ + STATS_OFFSET32(alignment_errors), /* 13 */ + STATS_OFFSET32(single_collision_transmit_frames), /* 14 */ + STATS_OFFSET32(multiple_collision_transmit_frames), /* 15 */ + STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), /* 16 */ + STATS_OFFSET32(excessive_collision_frames), /* 17 */ + STATS_OFFSET32(late_collision_frames), /* 18 */ + STATS_OFFSET32(number_of_bugs_found_in_stats_spec), /* 19 */ + STATS_OFFSET32(runt_packets_received), /* 20 */ + STATS_OFFSET32(jabber_packets_received), /* 21 */ + STATS_OFFSET32(error_runt_packets_received), /* 22 */ + STATS_OFFSET32(error_jabber_packets_received), /* 23 */ + STATS_OFFSET32(pause_xon_frames_received), /* 24 */ + STATS_OFFSET32(pause_xoff_frames_received), /* 25 */ + STATS_OFFSET32(pause_xon_frames_transmitted), /* 26 */ + STATS_OFFSET32(pause_xoff_frames_transmitted), /* 27 */ + STATS_OFFSET32(control_frames_received), /* 28 */ + STATS_OFFSET32(mac_filter_discard), /* 29 */ + STATS_OFFSET32(no_buff_discard), /* 30 */ +}; + +static u8 bnx2x_stats_len_arr[BNX2X_NUM_STATS] = { + 8, 0, 8, 0, 8, 8, 8, 8, 8, 8, + 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, +}; + +static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(buf, bnx2x_stats_str_arr, sizeof(bnx2x_stats_str_arr)); + break; + + case ETH_SS_TEST: + memcpy(buf, bnx2x_tests_str_arr, sizeof(bnx2x_tests_str_arr)); + break; + } +} + +static int bnx2x_get_stats_count(struct net_device *dev) +{ + return BNX2X_NUM_STATS; +} + +static void bnx2x_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *buf) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 *hw_stats = (u32 *)bnx2x_sp_check(bp, eth_stats); + int i; + + for (i = 0; i < BNX2X_NUM_STATS; i++) { + if (bnx2x_stats_len_arr[i] == 0) { + /* skip this counter */ + buf[i] = 0; + continue; + } + if (!hw_stats) { + buf[i] = 0; + continue; + } + if (bnx2x_stats_len_arr[i] == 4) { + /* 4-byte counter */ + buf[i] = (u64) *(hw_stats + bnx2x_stats_offset_arr[i]); + continue; + } + /* 8-byte counter */ + buf[i] = HILO_U64(*(hw_stats + bnx2x_stats_offset_arr[i]), + *(hw_stats + bnx2x_stats_offset_arr[i] + 1)); + } +} + +static int bnx2x_phys_id(struct net_device *dev, u32 data) +{ + struct bnx2x *bp = netdev_priv(dev); + int i; + + if (data == 0) + data = 2; + + for (i = 0; i < (data * 2); i++) { + if ((i % 2) == 0) { + bnx2x_leds_set(bp, SPEED_1000); + } else { + bnx2x_leds_unset(bp); + } + msleep_interruptible(500); + if (signal_pending(current)) + break; + } + + if (bp->link_up) + bnx2x_leds_set(bp, bp->line_speed); + + return 0; +} + +static struct ethtool_ops bnx2x_ethtool_ops = { + .get_settings = bnx2x_get_settings, + .set_settings = bnx2x_set_settings, + .get_drvinfo = bnx2x_get_drvinfo, + .get_wol = bnx2x_get_wol, + .set_wol = bnx2x_set_wol, + .get_msglevel = bnx2x_get_msglevel, + .set_msglevel = bnx2x_set_msglevel, + .nway_reset = bnx2x_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = bnx2x_get_eeprom_len, + .get_eeprom = bnx2x_get_eeprom, + .set_eeprom = bnx2x_set_eeprom, + .get_coalesce = bnx2x_get_coalesce, + .set_coalesce = bnx2x_set_coalesce, + .get_ringparam = bnx2x_get_ringparam, + .set_ringparam = bnx2x_set_ringparam, + .get_pauseparam = bnx2x_get_pauseparam, + .set_pauseparam = bnx2x_set_pauseparam, + .get_rx_csum = bnx2x_get_rx_csum, + .set_rx_csum = bnx2x_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = bnx2x_set_tso, + .self_test_count = bnx2x_self_test_count, + .self_test = bnx2x_self_test, + .get_strings = bnx2x_get_strings, + .phys_id = bnx2x_phys_id, + .get_stats_count = bnx2x_get_stats_count, + .get_ethtool_stats = bnx2x_get_ethtool_stats +}; + +/* end of ethtool_ops */ + +/**************************************************************************** +* General service functions +****************************************************************************/ + +static int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) +{ + u16 pmcsr; + + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); + + switch (state) { + case PCI_D0: + pci_write_config_word(bp->pdev, + bp->pm_cap + PCI_PM_CTRL, + ((pmcsr & ~PCI_PM_CTRL_STATE_MASK) | + PCI_PM_CTRL_PME_STATUS)); + + if (pmcsr & PCI_PM_CTRL_STATE_MASK) + /* delay required during transition out of D3hot */ + msleep(20); + break; + + case PCI_D3hot: + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= 3; + + if (bp->wol) + pmcsr |= PCI_PM_CTRL_PME_ENABLE; + + pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, + pmcsr); + + /* No more memory access after this point until + * device is brought back to D0. + */ + break; + + default: + return -EINVAL; + } + return 0; +} + +/* + * net_device service functions + */ + +/* Called with rtnl_lock from vlan functions and also netif_tx_lock + * from set_multicast. + */ +static void bnx2x_set_rx_mode(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + u32 rx_mode = BNX2X_RX_MODE_NORMAL; + + DP(NETIF_MSG_IFUP, "called dev->flags = %x\n", dev->flags); + + if (dev->flags & IFF_PROMISC) + rx_mode = BNX2X_RX_MODE_PROMISC; + + else if ((dev->flags & IFF_ALLMULTI) || + (dev->mc_count > BNX2X_MAX_MULTICAST)) + rx_mode = BNX2X_RX_MODE_ALLMULTI; + + else { /* some multicasts */ + int i, old, offset; + struct dev_mc_list *mclist; + struct mac_configuration_cmd *config = + bnx2x_sp(bp, mcast_config); + + for (i = 0, mclist = dev->mc_list; + mclist && (i < dev->mc_count); + i++, mclist = mclist->next) { + + config->config_table[i].cam_entry.msb_mac_addr = + swab16(*(u16 *)&mclist->dmi_addr[0]); + config->config_table[i].cam_entry.middle_mac_addr = + swab16(*(u16 *)&mclist->dmi_addr[2]); + config->config_table[i].cam_entry.lsb_mac_addr = + swab16(*(u16 *)&mclist->dmi_addr[4]); + config->config_table[i].cam_entry.flags = + cpu_to_le16(bp->port); + config->config_table[i].target_table_entry.flags = 0; + config->config_table[i].target_table_entry. + client_id = 0; + 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); + } + old = config->hdr.length_6b; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config->config_table[i])) { + i--; /* already invalidated */ + break; + } + /* invalidate */ + CAM_INVALIDATE(config->config_table[i]); + } + } + + if (CHIP_REV_IS_SLOW(bp)) + offset = BNX2X_MAX_EMUL_MULTI*(1 + bp->port); + else + offset = BNX2X_MAX_MULTICAST*(1 + bp->port); + + config->hdr.length_6b = i; + config->hdr.offset = offset; + config->hdr.reserved0 = 0; + config->hdr.reserved1 = 0; + + 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); + } + + bp->rx_mode = rx_mode; + bnx2x_set_storm_rx_mode(bp); +} + +static int bnx2x_poll(struct napi_struct *napi, int budget) +{ + struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, + napi); + struct bnx2x *bp = fp->bp; + int work_done = 0; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + goto out_panic; +#endif + + prefetch(fp->tx_buf_ring[TX_BD(fp->tx_pkt_cons)].skb); + prefetch(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb); + prefetch((char *)(fp->rx_buf_ring[RX_BD(fp->rx_bd_cons)].skb) + 256); + + bnx2x_update_fpsb_idx(fp); + + if (le16_to_cpu(*fp->tx_cons_sb) != fp->tx_pkt_cons) + bnx2x_tx_int(fp, budget); + + + if (le16_to_cpu(*fp->rx_cons_sb) != fp->rx_comp_cons) + work_done = bnx2x_rx_int(fp, budget); + + + rmb(); /* bnx2x_has_work() reads the status block */ + + /* must not complete if we consumed full budget */ + if ((work_done < budget) && !bnx2x_has_work(fp)) { + +#ifdef BNX2X_STOP_ON_ERROR +out_panic: +#endif + netif_rx_complete(bp->dev, napi); + + bnx2x_ack_sb(bp, fp->index, USTORM_ID, + le16_to_cpu(fp->fp_u_idx), IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, fp->index, CSTORM_ID, + le16_to_cpu(fp->fp_c_idx), IGU_INT_ENABLE, 1); + } + + return work_done; +} + +/* Called with netif_tx_lock. + * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call + * netif_wake_queue(). + */ +static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + struct bnx2x_fastpath *fp; + struct sw_tx_bd *tx_buf; + struct eth_tx_bd *tx_bd; + struct eth_tx_parse_bd *pbd = NULL; + u16 pkt_prod, bd_prod; + int nbd, fp_index = 0; + dma_addr_t mapping; + +#ifdef BNX2X_STOP_ON_ERROR + if (unlikely(bp->panic)) + return NETDEV_TX_BUSY; +#endif + + fp_index = smp_processor_id() % (bp->num_queues); + + fp = &bp->fp[fp_index]; + if (unlikely(bnx2x_tx_avail(bp->fp) < + (skb_shinfo(skb)->nr_frags + 3))) { + bp->slowpath->eth_stats.driver_xoff++, + netif_stop_queue(dev); + BNX2X_ERR("BUG! Tx ring full when queue awake!\n"); + return NETDEV_TX_BUSY; + } + + /* + This is a bit ugly. First we use one BD which we mark as start, + then for TSO or xsum we have a parsing info BD, + and only then we have the rest of the TSO bds. + (don't forget to mark the last one as last, + and to unmap only AFTER you write to the BD ...) + I would like to thank DovH for this mess. + */ + + pkt_prod = fp->tx_pkt_prod++; + bd_prod = fp->tx_bd_prod; + bd_prod = TX_BD(bd_prod); + + /* get a tx_buff and first bd */ + tx_buf = &fp->tx_buf_ring[TX_BD(pkt_prod)]; + tx_bd = &fp->tx_desc_ring[bd_prod]; + + tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; + tx_bd->general_data = (UNICAST_ADDRESS << + ETH_TX_BD_ETH_ADDR_TYPE_SHIFT); + tx_bd->general_data |= 1; /* header nbd */ + + /* remeber the first bd of the packet */ + tx_buf->first_bd = bd_prod; + + DP(NETIF_MSG_TX_QUEUED, + "sending pkt %u @%p next_idx %u bd %u @%p\n", + pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_bd); + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + struct iphdr *iph = ip_hdr(skb); + u8 len; + + tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IP_CSUM; + + /* turn on parsing and get a bd */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + pbd = (void *)&fp->tx_desc_ring[bd_prod]; + len = ((u8 *)iph - (u8 *)skb->data) / 2; + + /* for now NS flag is not used in Linux */ + pbd->global_data = (len | + ((skb->protocol == ETH_P_8021Q) << + ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); + pbd->ip_hlen = ip_hdrlen(skb) / 2; + pbd->total_hlen = cpu_to_le16(len + pbd->ip_hlen); + if (iph->protocol == IPPROTO_TCP) { + struct tcphdr *th = tcp_hdr(skb); + + tx_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_TCP_CSUM; + pbd->tcp_flags = htonl(tcp_flag_word(skb)) & 0xFFFF; + pbd->total_hlen += cpu_to_le16(tcp_hdrlen(skb) / 2); + pbd->tcp_pseudo_csum = swab16(th->check); + + } else if (iph->protocol == IPPROTO_UDP) { + struct udphdr *uh = udp_hdr(skb); + + tx_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_TCP_CSUM; + pbd->total_hlen += cpu_to_le16(4); + pbd->global_data |= ETH_TX_PARSE_BD_CS_ANY_FLG; + pbd->cs_offset = 5; /* 10 >> 1 */ + pbd->tcp_pseudo_csum = 0; + /* HW bug: we need to subtract 10 bytes before the + * UDP header from the csum + */ + uh->check = (u16) ~csum_fold(csum_sub(uh->check, + csum_partial(((u8 *)(uh)-10), 10, 0))); + } + } + + if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb)) { + tx_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); + tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; + } else { + tx_bd->vlan = cpu_to_le16(pkt_prod); + } + + mapping = pci_map_single(bp->pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); + + tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + nbd = skb_shinfo(skb)->nr_frags + ((pbd == NULL)? 1 : 2); + tx_bd->nbd = cpu_to_le16(nbd); + tx_bd->nbytes = cpu_to_le16(skb_headlen(skb)); + + DP(NETIF_MSG_TX_QUEUED, "first bd @%p addr (%x:%x) nbd %d" + " nbytes %d flags %x vlan %u\n", + tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, tx_bd->nbd, + tx_bd->nbytes, tx_bd->bd_flags.as_bitfield, tx_bd->vlan); + + if (skb_shinfo(skb)->gso_size && + (skb->len > (bp->dev->mtu + ETH_HLEN))) { + int hlen = 2 * le32_to_cpu(pbd->total_hlen); + + DP(NETIF_MSG_TX_QUEUED, + "TSO packet len %d hlen %d total len %d tso size %d\n", + skb->len, hlen, skb_headlen(skb), + skb_shinfo(skb)->gso_size); + + tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_SW_LSO; + + if (tx_bd->nbytes > cpu_to_le16(hlen)) { + /* we split the first bd into headers and data bds + * to ease the pain of our fellow micocode engineers + * we use one mapping for both bds + * So far this has only been observed to happen + * in Other Operating Systems(TM) + */ + + /* first fix first bd */ + nbd++; + tx_bd->nbd = cpu_to_le16(nbd); + tx_bd->nbytes = cpu_to_le16(hlen); + + /* we only print this as an error + * because we don't think this will ever happen. + */ + BNX2X_ERR("TSO split header size is %d (%x:%x)" + " nbd %d\n", tx_bd->nbytes, tx_bd->addr_hi, + tx_bd->addr_lo, tx_bd->nbd); + + /* now get a new data bd + * (after the pbd) and fill it */ + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + tx_bd = &fp->tx_desc_ring[bd_prod]; + + tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping) + hlen); + tx_bd->nbytes = cpu_to_le16(skb_headlen(skb) - hlen); + tx_bd->vlan = cpu_to_le16(pkt_prod); + /* this marks the bd + * as one that has no individual mapping + * the FW ignors this flag in a bd not maked start + */ + tx_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_SW_LSO; + DP(NETIF_MSG_TX_QUEUED, + "TSO split data size is %d (%x:%x)\n", + tx_bd->nbytes, tx_bd->addr_hi, tx_bd->addr_lo); + } + + if (!pbd) { + /* supposed to be unreached + * (and therefore not handled properly...) + */ + BNX2X_ERR("LSO with no PBD\n"); + BUG(); + } + + pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + 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)); + pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; + } + + { + int i; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + tx_bd = &fp->tx_desc_ring[bd_prod]; + + mapping = pci_map_page(bp->pdev, frag->page, + frag->page_offset, + frag->size, PCI_DMA_TODEVICE); + + tx_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); + tx_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); + tx_bd->nbytes = cpu_to_le16(frag->size); + tx_bd->vlan = cpu_to_le16(pkt_prod); + tx_bd->bd_flags.as_bitfield = 0; + DP(NETIF_MSG_TX_QUEUED, "frag %d bd @%p" + " addr (%x:%x) nbytes %d flags %x\n", + i, tx_bd, tx_bd->addr_hi, tx_bd->addr_lo, + tx_bd->nbytes, tx_bd->bd_flags.as_bitfield); + } /* for */ + } + + /* now at last mark the bd as the last bd */ + tx_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_END_BD; + + DP(NETIF_MSG_TX_QUEUED, "last bd @%p flags %x\n", + tx_bd, tx_bd->bd_flags.as_bitfield); + + tx_buf->skb = skb; + + bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); + + /* now send a tx doorbell, counting the next bd + * if the packet contains or ends with it + */ + if (TX_BD_POFF(bd_prod) < nbd) + nbd++; + + if (pbd) + DP(NETIF_MSG_TX_QUEUED, + "PBD @%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, pbd->total_hlen); + + DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %u bd %d\n", nbd, bd_prod); + + fp->hw_tx_prods->bds_prod += cpu_to_le16(nbd); + mb(); /* FW restriction: must not reorder writing nbd and packets */ + fp->hw_tx_prods->packets_prod += cpu_to_le32(1); + DOORBELL(bp, fp_index, 0); + + mmiowb(); + + fp->tx_bd_prod = bd_prod; + dev->trans_start = jiffies; + + if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) { + netif_stop_queue(dev); + bp->slowpath->eth_stats.driver_xoff++; + if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3) + netif_wake_queue(dev); + } + fp->tx_pkt++; + + return NETDEV_TX_OK; +} + +static struct net_device_stats *bnx2x_get_stats(struct net_device *dev) +{ + return &dev->stats; +} + +/* Called with rtnl_lock */ +static int bnx2x_open(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + bnx2x_set_power_state(bp, PCI_D0); + + return bnx2x_nic_load(bp, 1); +} + +/* Called with rtnl_lock */ +static int bnx2x_close(struct net_device *dev) +{ + int rc; + struct bnx2x *bp = netdev_priv(dev); + + /* Unload the driver, release IRQs */ + rc = bnx2x_nic_unload(bp, 1); + if (rc) { + BNX2X_ERR("bnx2x_nic_unload failed: %d\n", rc); + return rc; + } + bnx2x_set_power_state(bp, PCI_D3hot); + + return 0; +} + +/* Called with rtnl_lock */ +static int bnx2x_change_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + struct bnx2x *bp = netdev_priv(dev); + + if (!is_valid_ether_addr(addr->sa_data)) + return -EINVAL; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + if (netif_running(dev)) + bnx2x_set_mac_addr(bp); + + return 0; +} + +/* Called with rtnl_lock */ +static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mii_ioctl_data *data = if_mii(ifr); + struct bnx2x *bp = netdev_priv(dev); + int err; + + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = bp->phy_addr; + + /* fallthru */ + case SIOCGMIIREG: { + u32 mii_regval; + + spin_lock_bh(&bp->phy_lock); + if (bp->state == BNX2X_STATE_OPEN) { + err = bnx2x_mdio22_read(bp, data->reg_num & 0x1f, + &mii_regval); + + data->val_out = mii_regval; + } else { + err = -EAGAIN; + } + spin_unlock_bh(&bp->phy_lock); + return err; + } + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + spin_lock_bh(&bp->phy_lock); + if (bp->state == BNX2X_STATE_OPEN) { + err = bnx2x_mdio22_write(bp, data->reg_num & 0x1f, + data->val_in); + } else { + err = -EAGAIN; + } + spin_unlock_bh(&bp->phy_lock); + return err; + + default: + /* do nothing */ + break; + } + + return -EOPNOTSUPP; +} + +/* Called with rtnl_lock */ +static int bnx2x_change_mtu(struct net_device *dev, int new_mtu) +{ + struct bnx2x *bp = netdev_priv(dev); + + if ((new_mtu > ETH_MAX_JUMBO_PACKET_SIZE) || + ((new_mtu + ETH_HLEN) < ETH_MIN_PACKET_SIZE)) + return -EINVAL; + + /* This does not race with packet allocation + * because the actuall alloc size is + * only updated as part of load + */ + dev->mtu = new_mtu; + + if (netif_running(dev)) { + bnx2x_nic_unload(bp, 0); + bnx2x_nic_load(bp, 0); + } + return 0; +} + +static void bnx2x_tx_timeout(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + +#ifdef BNX2X_STOP_ON_ERROR + if (!bp->panic) + bnx2x_panic(); +#endif + /* This allows the netif to be shutdown gracefully before resetting */ + schedule_work(&bp->reset_task); +} + +#ifdef BCM_VLAN +/* Called with rtnl_lock */ +static void bnx2x_vlan_rx_register(struct net_device *dev, + struct vlan_group *vlgrp) +{ + struct bnx2x *bp = netdev_priv(dev); + + bp->vlgrp = vlgrp; + if (netif_running(dev)) + bnx2x_set_rx_mode(dev); +} +#endif + +#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER) +static void poll_bnx2x(struct net_device *dev) +{ + struct bnx2x *bp = netdev_priv(dev); + + disable_irq(bp->pdev->irq); + bnx2x_interrupt(bp->pdev->irq, dev); + enable_irq(bp->pdev->irq); +} +#endif + +static void bnx2x_reset_task(struct work_struct *work) +{ + struct bnx2x *bp = container_of(work, struct bnx2x, reset_task); + +#ifdef BNX2X_STOP_ON_ERROR + BNX2X_ERR("reset task called but STOP_ON_ERROR defined" + " so reset not done to allow debug dump,\n" + KERN_ERR " you will need to reboot when done\n"); + return; +#endif + + if (!netif_running(bp->dev)) + return; + + bp->in_reset_task = 1; + + bnx2x_netif_stop(bp); + + bnx2x_nic_unload(bp, 0); + bnx2x_nic_load(bp, 0); + + bp->in_reset_task = 0; +} + +static int __devinit bnx2x_init_board(struct pci_dev *pdev, + struct net_device *dev) +{ + struct bnx2x *bp; + int rc; + + SET_NETDEV_DEV(dev, &pdev->dev); + bp = netdev_priv(dev); + + bp->flags = 0; + bp->port = PCI_FUNC(pdev->devfn); + + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR PFX "Cannot enable PCI device, aborting\n"); + goto err_out; + } + + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { + printk(KERN_ERR PFX "Cannot find PCI device base address," + " aborting\n"); + rc = -ENODEV; + goto err_out_disable; + } + + if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) { + printk(KERN_ERR PFX "Cannot find second PCI device" + " base address, aborting\n"); + rc = -ENODEV; + goto err_out_disable; + } + + rc = pci_request_regions(pdev, DRV_MODULE_NAME); + if (rc) { + printk(KERN_ERR PFX "Cannot obtain PCI resources," + " aborting\n"); + goto err_out_disable; + } + + pci_set_master(pdev); + + bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (bp->pm_cap == 0) { + printk(KERN_ERR PFX "Cannot find power management" + " capability, aborting\n"); + rc = -EIO; + goto err_out_release; + } + + bp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (bp->pcie_cap == 0) { + printk(KERN_ERR PFX "Cannot find PCI Express capability," + " aborting\n"); + rc = -EIO; + goto err_out_release; + } + + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { + bp->flags |= USING_DAC_FLAG; + if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { + printk(KERN_ERR PFX "pci_set_consistent_dma_mask" + " failed, aborting\n"); + rc = -EIO; + goto err_out_release; + } + + } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) { + printk(KERN_ERR PFX "System does not support DMA," + " aborting\n"); + rc = -EIO; + goto err_out_release; + } + + bp->dev = dev; + bp->pdev = pdev; + + spin_lock_init(&bp->phy_lock); + + bp->in_reset_task = 0; + + INIT_WORK(&bp->reset_task, bnx2x_reset_task); + INIT_WORK(&bp->sp_task, bnx2x_sp_task); + + dev->base_addr = pci_resource_start(pdev, 0); + + dev->irq = pdev->irq; + + bp->regview = ioremap_nocache(dev->base_addr, + pci_resource_len(pdev, 0)); + if (!bp->regview) { + printk(KERN_ERR PFX "Cannot map register space, aborting\n"); + rc = -ENOMEM; + goto err_out_release; + } + + bp->doorbells = ioremap_nocache(pci_resource_start(pdev , 2), + pci_resource_len(pdev, 2)); + if (!bp->doorbells) { + printk(KERN_ERR PFX "Cannot map doorbell space, aborting\n"); + rc = -ENOMEM; + goto err_out_unmap; + } + + bnx2x_set_power_state(bp, PCI_D0); + + bnx2x_get_hwinfo(bp); + + if (CHIP_REV(bp) == CHIP_REV_FPGA) { + printk(KERN_ERR PFX "FPGA detacted. MCP disabled," + " will only init first device\n"); + onefunc = 1; + nomcp = 1; + } + + if (nomcp) { + printk(KERN_ERR PFX "MCP disabled, will only" + " init first device\n"); + onefunc = 1; + } + + if (onefunc && bp->port) { + printk(KERN_ERR PFX "Second device disabled, exiting\n"); + rc = -ENODEV; + goto err_out_unmap; + } + + bp->tx_ring_size = MAX_TX_AVAIL; + bp->rx_ring_size = MAX_RX_AVAIL; + + bp->rx_csum = 1; + + bp->rx_offset = 0; + + bp->tx_quick_cons_trip_int = 0xff; + bp->tx_quick_cons_trip = 0xff; + bp->tx_ticks_int = 50; + bp->tx_ticks = 50; + + bp->rx_quick_cons_trip_int = 0xff; + bp->rx_quick_cons_trip = 0xff; + bp->rx_ticks_int = 25; + bp->rx_ticks = 25; + + bp->stats_ticks = 1000000 & 0xffff00; + + bp->timer_interval = HZ; + bp->current_interval = (poll ? poll : HZ); + + init_timer(&bp->timer); + bp->timer.expires = jiffies + bp->current_interval; + bp->timer.data = (unsigned long) bp; + bp->timer.function = bnx2x_timer; + + return 0; + +err_out_unmap: + if (bp->regview) { + iounmap(bp->regview); + bp->regview = NULL; + } + + if (bp->doorbells) { + iounmap(bp->doorbells); + bp->doorbells = NULL; + } + +err_out_release: + pci_release_regions(pdev); + +err_out_disable: + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + +err_out: + return rc; +} + +static int __devinit bnx2x_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + static int version_printed; + struct net_device *dev = NULL; + struct bnx2x *bp; + int rc, i; + int port = PCI_FUNC(pdev->devfn); + + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); + + /* dev zeroed in init_etherdev */ + dev = alloc_etherdev(sizeof(*bp)); + if (!dev) + return -ENOMEM; + + netif_carrier_off(dev); + + bp = netdev_priv(dev); + bp->msglevel = debug; + + if (port && onefunc) { + printk(KERN_ERR PFX "second function disabled. exiting\n"); + return 0; + } + + rc = bnx2x_init_board(pdev, dev); + if (rc < 0) { + free_netdev(dev); + return rc; + } + + dev->hard_start_xmit = bnx2x_start_xmit; + dev->watchdog_timeo = TX_TIMEOUT; + + dev->get_stats = bnx2x_get_stats; + dev->ethtool_ops = &bnx2x_ethtool_ops; + dev->open = bnx2x_open; + dev->stop = bnx2x_close; + dev->set_multicast_list = bnx2x_set_rx_mode; + dev->set_mac_address = bnx2x_change_mac_addr; + dev->do_ioctl = bnx2x_ioctl; + dev->change_mtu = bnx2x_change_mtu; + dev->tx_timeout = bnx2x_tx_timeout; +#ifdef BCM_VLAN + dev->vlan_rx_register = bnx2x_vlan_rx_register; +#endif +#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER) + dev->poll_controller = poll_bnx2x; +#endif + dev->features |= NETIF_F_SG; + if (bp->flags & USING_DAC_FLAG) + dev->features |= NETIF_F_HIGHDMA; + dev->features |= NETIF_F_IP_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; + + rc = register_netdev(dev); + if (rc) { + printk(KERN_ERR PFX "Cannot register net device\n"); + if (bp->regview) + iounmap(bp->regview); + if (bp->doorbells) + iounmap(bp->doorbells); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + free_netdev(dev); + return rc; + } + + pci_set_drvdata(pdev, dev); + + bp->name = board_info[ent->driver_data].name; + printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz " + "found at mem %lx, IRQ %d, ", + dev->name, bp->name, + ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', + ((CHIP_ID(bp) & 0x0ff0) >> 4), + ((bp->flags & PCIX_FLAG) ? "-X" : ""), + ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), + bp->bus_speed_mhz, + dev->base_addr, + bp->pdev->irq); + + printk("node addr "); + for (i = 0; i < 6; i++) + printk("%2.2x", dev->dev_addr[i]); + printk("\n"); + + return 0; +} + +static void __devexit bnx2x_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2x *bp = netdev_priv(dev); + + flush_scheduled_work(); + /*tasklet_kill(&bp->sp_task);*/ + unregister_netdev(dev); + + if (bp->regview) + iounmap(bp->regview); + + if (bp->doorbells) + iounmap(bp->doorbells); + + free_netdev(dev); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2x *bp = netdev_priv(dev); + int rc; + + if (!netif_running(dev)) + return 0; + + rc = bnx2x_nic_unload(bp, 0); + if (!rc) + return rc; + + netif_device_detach(dev); + pci_save_state(pdev); + + bnx2x_set_power_state(bp, pci_choose_state(pdev, state)); + return 0; +} + +static int bnx2x_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2x *bp = netdev_priv(dev); + int rc; + + if (!netif_running(dev)) + return 0; + + pci_restore_state(pdev); + + bnx2x_set_power_state(bp, PCI_D0); + netif_device_attach(dev); + + rc = bnx2x_nic_load(bp, 0); + if (rc) + return rc; + + return 0; +} + +static struct pci_driver bnx2x_pci_driver = { + .name = DRV_MODULE_NAME, + .id_table = bnx2x_pci_tbl, + .probe = bnx2x_init_one, + .remove = __devexit_p(bnx2x_remove_one), + .suspend = bnx2x_suspend, + .resume = bnx2x_resume, +}; + +static int __init bnx2x_init(void) +{ + return pci_register_driver(&bnx2x_pci_driver); +} + +static void __exit bnx2x_cleanup(void) +{ + pci_unregister_driver(&bnx2x_pci_driver); +} + +module_init(bnx2x_init); +module_exit(bnx2x_cleanup); + diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h new file mode 100644 index 0000000..4f7ae6f --- /dev/null +++ b/drivers/net/bnx2x.h @@ -0,0 +1,1071 @@ +/* bnx2x.h: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + * + * Written by: Eliezer Tamir + * Based on code from Michael Chan's bnx2 driver + */ + +#ifndef BNX2X_H +#define BNX2X_H + +/* error/debug prints */ + +#define DRV_MODULE_NAME "bnx2x" +#define PFX DRV_MODULE_NAME ": " + +/* for messages that are currently off */ +#define BNX2X_MSG_OFF 0 +#define BNX2X_MSG_MCP 0x10000 /* was: NETIF_MSG_HW */ +#define BNX2X_MSG_STATS 0x20000 /* was: NETIF_MSG_TIMER */ +#define NETIF_MSG_NVM 0x40000 /* was: NETIF_MSG_HW */ +#define NETIF_MSG_DMAE 0x80000 /* was: NETIF_MSG_HW */ + +#define DP_LEVEL KERN_NOTICE /* was: KERN_DEBUG */ + +/* regular debug print */ +#define DP(__mask, __fmt, __args...) do { \ + if (bp->msglevel & (__mask)) \ + printk(DP_LEVEL "[%s:%d(%s)]" __fmt, __FUNCTION__, \ + __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ + } while (0) + +/* for errors (never masked) */ +#define BNX2X_ERR(__fmt, __args...) do { \ + printk(KERN_ERR "[%s:%d(%s)]" __fmt, __FUNCTION__, \ + __LINE__, bp->dev?(bp->dev->name):"?", ##__args); \ + } while (0) + +/* before we have a dev->name use dev_info() */ +#define BNX2X_DEV_INFO(__fmt, __args...) do { \ + if (bp->msglevel & NETIF_MSG_PROBE) \ + dev_info(&bp->pdev->dev, __fmt, ##__args); \ + } while (0) + + +#ifdef BNX2X_STOP_ON_ERROR +#define bnx2x_panic() do { \ + bp->panic = 1; \ + BNX2X_ERR("driver assert\n"); \ + bnx2x_disable_int(bp); \ + bnx2x_panic_dump(bp); \ + } while (0) +#else +#define bnx2x_panic() do { \ + BNX2X_ERR("driver assert\n"); \ + bnx2x_panic_dump(bp); \ + } while (0) +#endif + + +#define U64_LO(x) (((u64)x) & 0xffffffff) +#define U64_HI(x) (((u64)x) >> 32) +#define HILO_U64(hi, lo) (((u64)hi << 32) + lo) + + +#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_RD64(bp, offset) readq(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)) +#define REG_WR16(bp, offset, val) writew((u16)val, REG_ADDR(bp, offset)) +#define REG_WR32(bp, offset, val) REG_WR(bp, offset, val) + +#define REG_RD_IND(bp, offset) bnx2x_reg_rd_ind(bp, offset) +#define REG_WR_IND(bp, offset, val) bnx2x_reg_wr_ind(bp, offset, val) + +#define REG_WR_DMAE(bp, offset, val, len32) \ + do { \ + memcpy(bnx2x_sp(bp, wb_data[0]), val, len32 * 4); \ + bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), \ + offset, len32); \ + } while (0) + +#define SHMEM_RD(bp, type) \ + REG_RD(bp, bp->shmem_base + offsetof(struct shmem_region, type)) +#define SHMEM_WR(bp, type, val) \ + REG_WR(bp, bp->shmem_base + offsetof(struct shmem_region, type), val) + +#define NIG_WR(reg, val) REG_WR(bp, reg, val) +#define EMAC_WR(reg, val) REG_WR(bp, emac_base + reg, val) +#define BMAC_WR(reg, val) REG_WR(bp, GRCBASE_NIG + bmac_addr + reg, val) + + +#define for_each_queue(bp, var) for (var = 0; var < bp->num_queues; var++) + +#define for_each_nondefault_queue(bp, var) \ + for (var = 1; var < bp->num_queues; var++) +#define is_multi(bp) (bp->num_queues > 1) + + +struct regp { + u32 lo; + u32 hi; +}; + +struct bmac_stats { + struct regp tx_gtpkt; + struct regp tx_gtxpf; + struct regp tx_gtfcs; + struct regp tx_gtmca; + struct regp tx_gtgca; + struct regp tx_gtfrg; + struct regp tx_gtovr; + struct regp tx_gt64; + struct regp tx_gt127; + struct regp tx_gt255; /* 10 */ + struct regp tx_gt511; + struct regp tx_gt1023; + struct regp tx_gt1518; + struct regp tx_gt2047; + struct regp tx_gt4095; + struct regp tx_gt9216; + struct regp tx_gt16383; + struct regp tx_gtmax; + struct regp tx_gtufl; + struct regp tx_gterr; /* 20 */ + struct regp tx_gtbyt; + + struct regp rx_gr64; + struct regp rx_gr127; + struct regp rx_gr255; + struct regp rx_gr511; + struct regp rx_gr1023; + struct regp rx_gr1518; + struct regp rx_gr2047; + struct regp rx_gr4095; + struct regp rx_gr9216; /* 30 */ + struct regp rx_gr16383; + struct regp rx_grmax; + struct regp rx_grpkt; + struct regp rx_grfcs; + struct regp rx_grmca; + struct regp rx_grbca; + struct regp rx_grxcf; + struct regp rx_grxpf; + struct regp rx_grxuo; + struct regp rx_grjbr; /* 40 */ + struct regp rx_grovr; + struct regp rx_grflr; + struct regp rx_grmeg; + struct regp rx_grmeb; + struct regp rx_grbyt; + struct regp rx_grund; + struct regp rx_grfrg; + struct regp rx_grerb; + struct regp rx_grfre; + struct regp rx_gripj; /* 50 */ +}; + +struct emac_stats { + u32 rx_ifhcinoctets ; + u32 rx_ifhcinbadoctets ; + u32 rx_etherstatsfragments ; + u32 rx_ifhcinucastpkts ; + u32 rx_ifhcinmulticastpkts ; + u32 rx_ifhcinbroadcastpkts ; + u32 rx_dot3statsfcserrors ; + u32 rx_dot3statsalignmenterrors ; + u32 rx_dot3statscarriersenseerrors ; + u32 rx_xonpauseframesreceived ; /* 10 */ + u32 rx_xoffpauseframesreceived ; + u32 rx_maccontrolframesreceived ; + u32 rx_xoffstateentered ; + u32 rx_dot3statsframestoolong ; + u32 rx_etherstatsjabbers ; + u32 rx_etherstatsundersizepkts ; + u32 rx_etherstatspkts64octets ; + u32 rx_etherstatspkts65octetsto127octets ; + u32 rx_etherstatspkts128octetsto255octets ; + u32 rx_etherstatspkts256octetsto511octets ; /* 20 */ + u32 rx_etherstatspkts512octetsto1023octets ; + u32 rx_etherstatspkts1024octetsto1522octets; + u32 rx_etherstatspktsover1522octets ; + + u32 rx_falsecarriererrors ; + + u32 tx_ifhcoutoctets ; + u32 tx_ifhcoutbadoctets ; + u32 tx_etherstatscollisions ; + u32 tx_outxonsent ; + u32 tx_outxoffsent ; + u32 tx_flowcontroldone ; /* 30 */ + u32 tx_dot3statssinglecollisionframes ; + u32 tx_dot3statsmultiplecollisionframes ; + u32 tx_dot3statsdeferredtransmissions ; + u32 tx_dot3statsexcessivecollisions ; + u32 tx_dot3statslatecollisions ; + u32 tx_ifhcoutucastpkts ; + u32 tx_ifhcoutmulticastpkts ; + u32 tx_ifhcoutbroadcastpkts ; + u32 tx_etherstatspkts64octets ; + u32 tx_etherstatspkts65octetsto127octets ; /* 40 */ + u32 tx_etherstatspkts128octetsto255octets ; + u32 tx_etherstatspkts256octetsto511octets ; + u32 tx_etherstatspkts512octetsto1023octets ; + u32 tx_etherstatspkts1024octetsto1522octet ; + u32 tx_etherstatspktsover1522octets ; + u32 tx_dot3statsinternalmactransmiterrors ; /* 46 */ +}; + +union mac_stats { + struct emac_stats emac; + struct bmac_stats bmac; +}; + +struct nig_stats { + u32 brb_discard; + u32 brb_packet; + u32 brb_truncate; + u32 flow_ctrl_discard; + u32 flow_ctrl_octets; + u32 flow_ctrl_packet; + u32 mng_discard; + u32 mng_octet_inp; + u32 mng_octet_out; + u32 mng_packet_inp; + u32 mng_packet_out; + u32 pbf_octets; + u32 pbf_packet; + u32 safc_inp; + u32 done; + u32 pad; +}; + +struct bnx2x_eth_stats { + u32 pad; /* to make long counters u64 aligned */ + u32 mac_stx_start; + u32 total_bytes_received_hi; + u32 total_bytes_received_lo; + u32 total_bytes_transmitted_hi; + u32 total_bytes_transmitted_lo; + u32 total_unicast_packets_received_hi; + u32 total_unicast_packets_received_lo; + u32 total_multicast_packets_received_hi; + u32 total_multicast_packets_received_lo; + u32 total_broadcast_packets_received_hi; + u32 total_broadcast_packets_received_lo; + u32 total_unicast_packets_transmitted_hi; + u32 total_unicast_packets_transmitted_lo; + u32 total_multicast_packets_transmitted_hi; + u32 total_multicast_packets_transmitted_lo; + u32 total_broadcast_packets_transmitted_hi; + u32 total_broadcast_packets_transmitted_lo; + u32 crc_receive_errors; + u32 alignment_errors; + u32 false_carrier_detections; + u32 runt_packets_received; + u32 jabber_packets_received; + u32 pause_xon_frames_received; + u32 pause_xoff_frames_received; + u32 pause_xon_frames_transmitted; + u32 pause_xoff_frames_transmitted; + u32 single_collision_transmit_frames; + u32 multiple_collision_transmit_frames; + u32 late_collision_frames; + u32 excessive_collision_frames; + u32 control_frames_received; + u32 frames_received_64_bytes; + u32 frames_received_65_127_bytes; + u32 frames_received_128_255_bytes; + u32 frames_received_256_511_bytes; + u32 frames_received_512_1023_bytes; + u32 frames_received_1024_1522_bytes; + u32 frames_received_1523_9022_bytes; + u32 frames_transmitted_64_bytes; + u32 frames_transmitted_65_127_bytes; + u32 frames_transmitted_128_255_bytes; + u32 frames_transmitted_256_511_bytes; + u32 frames_transmitted_512_1023_bytes; + u32 frames_transmitted_1024_1522_bytes; + u32 frames_transmitted_1523_9022_bytes; + u32 valid_bytes_received_hi; + u32 valid_bytes_received_lo; + u32 error_runt_packets_received; + u32 error_jabber_packets_received; + u32 mac_stx_end; + + u32 pad2; + u32 stat_IfHCInBadOctets_hi; + u32 stat_IfHCInBadOctets_lo; + u32 stat_IfHCOutBadOctets_hi; + u32 stat_IfHCOutBadOctets_lo; + u32 stat_Dot3statsFramesTooLong; + u32 stat_Dot3statsInternalMacTransmitErrors; + u32 stat_Dot3StatsCarrierSenseErrors; + u32 stat_Dot3StatsDeferredTransmissions; + u32 stat_FlowControlDone; + u32 stat_XoffStateEntered; + + u32 x_total_sent_bytes_hi; + u32 x_total_sent_bytes_lo; + u32 x_total_sent_pkts; + + u32 t_rcv_unicast_bytes_hi; + u32 t_rcv_unicast_bytes_lo; + u32 t_rcv_broadcast_bytes_hi; + u32 t_rcv_broadcast_bytes_lo; + u32 t_rcv_multicast_bytes_hi; + u32 t_rcv_multicast_bytes_lo; + u32 t_total_rcv_pkt; + + u32 checksum_discard; + u32 packets_too_big_discard; + u32 no_buff_discard; + u32 ttl0_discard; + u32 mac_discard; + u32 mac_filter_discard; + u32 xxoverflow_discard; + u32 brb_truncate_discard; + + u32 brb_discard; + u32 brb_packet; + u32 brb_truncate; + u32 flow_ctrl_discard; + u32 flow_ctrl_octets; + u32 flow_ctrl_packet; + u32 mng_discard; + u32 mng_octet_inp; + u32 mng_octet_out; + u32 mng_packet_inp; + u32 mng_packet_out; + u32 pbf_octets; + u32 pbf_packet; + u32 safc_inp; + u32 driver_xoff; + u32 number_of_bugs_found_in_stats_spec; /* just kidding */ +}; + +#define MAC_STX_NA 0xffffffff + +#ifdef BNX2X_MULTI +#define MAX_CONTEXT 16 +#else +#define MAX_CONTEXT 1 +#endif + +union cdu_context { + struct eth_context eth; + char pad[1024]; +}; + +#define MAX_DMAE_C 5 + +/* 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; + + /* used by dmae command executer */ + struct dmae_command dmae[MAX_DMAE_C]; + + union mac_stats mac_stats; + struct nig_stats nig; + struct bnx2x_eth_stats eth_stats; + + u32 wb_comp; +#define BNX2X_WB_COMP_VAL 0xe0d0d0ae + u32 wb_data[4]; +}; + +#define bnx2x_sp(bp, var) (&bp->slowpath->var) +#define bnx2x_sp_check(bp, var) ((bp->slowpath) ? (&bp->slowpath->var) : NULL) +#define bnx2x_sp_mapping(bp, var) \ + (bp->slowpath_mapping + offsetof(struct bnx2x_slowpath, var)) + + +struct sw_rx_bd { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(mapping) +}; + +struct sw_tx_bd { + struct sk_buff *skb; + u16 first_bd; +}; + +struct bnx2x_fastpath { + + struct napi_struct napi; + + struct host_status_block *status_blk; + dma_addr_t status_blk_mapping; + + struct eth_tx_db_data *hw_tx_prods; + dma_addr_t tx_prods_mapping; + + struct sw_tx_bd *tx_buf_ring; + + struct eth_tx_bd *tx_desc_ring; + dma_addr_t tx_desc_mapping; + + struct sw_rx_bd *rx_buf_ring; + + struct eth_rx_bd *rx_desc_ring; + dma_addr_t rx_desc_mapping; + + union eth_rx_cqe *rx_comp_ring; + dma_addr_t rx_comp_mapping; + + int state; +#define BNX2X_FP_STATE_CLOSED 0 +#define BNX2X_FP_STATE_IRQ 0x80000 +#define BNX2X_FP_STATE_OPENING 0x90000 +#define BNX2X_FP_STATE_OPEN 0xa0000 +#define BNX2X_FP_STATE_HALTING 0xb0000 +#define BNX2X_FP_STATE_HALTED 0xc0000 +#define BNX2X_FP_STATE_DELETED 0xd0000 +#define BNX2X_FP_STATE_CLOSE_IRQ 0xe0000 + + int index; + + u16 tx_pkt_prod; + u16 tx_pkt_cons; + u16 tx_bd_prod; + u16 tx_bd_cons; + u16 *tx_cons_sb; + + u16 fp_c_idx; + u16 fp_u_idx; + + u16 rx_bd_prod; + u16 rx_bd_cons; + u16 rx_comp_prod; + u16 rx_comp_cons; + u16 *rx_cons_sb; + + unsigned long tx_pkt, + rx_pkt, + rx_calls; + + struct bnx2x *bp; /* parent */ +}; + +#define bnx2x_fp(bp, nr, var) (bp->fp[nr].var) + + +/* attn group wiring */ +#define MAX_DYNAMIC_ATTN_GRPS 8 + +struct attn_route { + u32 sig[4]; +}; + +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; + void __iomem *regview; + void __iomem *doorbells; + + struct net_device *dev; + struct pci_dev *pdev; + + atomic_t intr_sem; + struct msix_entry msix_table[MAX_CONTEXT+1]; + + int tx_ring_size; + +#ifdef BCM_VLAN + struct vlan_group *vlgrp; +#endif + + u32 rx_csum; + u32 rx_offset; + u32 rx_buf_use_size; /* useable size */ + u32 rx_buf_size; /* with alignment */ +#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ +#define ETH_MIN_PACKET_SIZE 60 +#define ETH_MAX_PACKET_SIZE 1500 +#define ETH_MAX_JUMBO_PACKET_SIZE 9600 + + struct host_def_status_block *def_status_blk; +#define DEF_SB_ID 16 + u16 def_c_idx; + u16 def_u_idx; + u16 def_t_idx; + u16 def_x_idx; + u16 def_att_idx; + u32 attn_state; + struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; + u32 aeu_mask; + u32 nig_mask; + + /* slow path ring */ + struct eth_spe *spq; + dma_addr_t spq_mapping; + u16 spq_prod_idx; + u16 dsb_sp_prod_idx; + struct eth_spe *spq_prod_bd; + struct eth_spe *spq_last_bd; + u16 *dsb_sp_prod; + u16 spq_left; /* serialize spq */ + spinlock_t spq_lock; + + /* Flag for marking that there is either + * STAT_QUERY or CFC DELETE ramrod pending + */ + u8 stat_pending; + + /* End of fileds used in the performance code paths */ + + int panic; + int msglevel; + + u32 flags; +#define PCIX_FLAG 1 +#define PCI_32BIT_FLAG 2 +#define ONE_TDMA_FLAG 4 /* no longer used */ +#define NO_WOL_FLAG 8 +#define USING_DAC_FLAG 0x10 +#define USING_MSIX_FLAG 0x20 +#define ASF_ENABLE_FLAG 0x40 + + int port; + + int pm_cap; + int pcie_cap; + + /* Used to synchronize phy accesses */ + spinlock_t phy_lock; + + struct work_struct reset_task; + u16 in_reset_task; + + struct work_struct sp_task; + + struct timer_list timer; + int timer_interval; + int current_interval; + + u32 shmem_base; + + u32 chip_id; +/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ +#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) + +#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) +#define CHIP_NUM_5710 0x57100000 + +#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) +#define CHIP_REV_Ax 0x00000000 +#define CHIP_REV_Bx 0x00001000 +#define CHIP_REV_Cx 0x00002000 +#define CHIP_REV_EMUL 0x0000e000 +#define CHIP_REV_FPGA 0x0000f000 +#define CHIP_REV_IS_SLOW(bp) ((CHIP_REV(bp) == CHIP_REV_EMUL) || \ + (CHIP_REV(bp) == CHIP_REV_FPGA)) + +#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0) +#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0x0000000f) + + u16 fw_seq; + u16 fw_drv_pulse_wr_seq; + u32 fw_mb; + + u32 hw_config; + u32 serdes_config; + u32 lane_config; + u32 ext_phy_config; +#define XGXS_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \ + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK) +#define SERDES_EXT_PHY_TYPE(bp) (bp->ext_phy_config & \ + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) + + u32 speed_cap_mask; + u32 link_config; +#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 +#define SWITCH_CFG_ONE_TIME_DETECT \ + PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT + + u8 ser_lane; + u8 rx_lane_swap; + u8 tx_lane_swap; + + u8 link_up; + + u32 supported; +/* link settings - missing defines */ +#define SUPPORTED_2500baseT_Full (1 << 15) +#define SUPPORTED_CX4 (1 << 16) + + u32 phy_flags; +/*#define PHY_SERDES_FLAG 0x1*/ +#define PHY_BMAC_FLAG 0x2 +#define PHY_EMAC_FLAG 0x4 +#define PHY_XGXS_FLAG 0x8 +#define PHY_SGMII_FLAG 0x10 +#define PHY_INT_MODE_MASK_FLAG 0x300 +#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 +#define PHY_INT_MODE_LINK_READY_FLAG 0x200 + + u32 phy_addr; + u32 phy_id; + + u32 autoneg; +#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 +#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 +#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM +#define AUTONEG_PARALLEL \ + SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION +#define AUTONEG_SGMII_FIBER_AUTODET \ + SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT +#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY + + u32 req_autoneg; +#define AUTONEG_SPEED 0x1 +#define AUTONEG_FLOW_CTRL 0x2 + + u32 req_line_speed; +/* link settings - missing defines */ +#define SPEED_12000 12000 +#define SPEED_12500 12500 +#define SPEED_13000 13000 +#define SPEED_15000 15000 +#define SPEED_16000 16000 + + u32 req_duplex; + u32 req_flow_ctrl; +#define FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO +#define FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX +#define FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX +#define FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH +#define FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE + + u32 pause_mode; +#define PAUSE_NONE 0 +#define PAUSE_SYMMETRIC 1 +#define PAUSE_ASYMMETRIC 2 +#define PAUSE_BOTH 3 + + u32 advertising; +/* link settings - missing defines */ +#define ADVERTISED_2500baseT_Full (1 << 15) +#define ADVERTISED_CX4 (1 << 16) + + u32 link_status; + u32 line_speed; + u32 duplex; + u32 flow_ctrl; + + u32 bc_ver; + + int flash_size; +#define NVRAM_1MB_SIZE 0x20000 /* 1M bit in bytes */ +#define NVRAM_TIMEOUT_COUNT 30000 +#define NVRAM_PAGE_SIZE 256 + + int rx_ring_size; + + u16 tx_quick_cons_trip_int; + u16 tx_quick_cons_trip; + u16 tx_ticks_int; + u16 tx_ticks; + + u16 rx_quick_cons_trip_int; + u16 rx_quick_cons_trip; + u16 rx_ticks_int; + u16 rx_ticks; + + u32 stats_ticks; + + int state; +#define BNX2X_STATE_CLOSED 0x0 +#define BNX2X_STATE_OPENING_WAIT4_LOAD 0x1000 +#define BNX2X_STATE_OPENING_WAIT4_PORT 0x2000 +#define BNX2X_STATE_OPEN 0x3000 +#define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 +#define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 +#define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 +#define BNX2X_STATE_ERROR 0xF000 + + int num_queues; + + u32 rx_mode; +#define BNX2X_RX_MODE_NONE 0 +#define BNX2X_RX_MODE_NORMAL 1 +#define BNX2X_RX_MODE_ALLMULTI 2 +#define BNX2X_RX_MODE_PROMISC 3 +#define BNX2X_MAX_MULTICAST 64 +#define BNX2X_MAX_EMUL_MULTI 16 + + dma_addr_t def_status_blk_mapping; + + struct bnx2x_slowpath *slowpath; + dma_addr_t slowpath_mapping; + +#ifdef BCM_ISCSI + 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; +#endif + + char *name; + u16 bus_speed_mhz; + u8 wol; + u8 pad; + + /* used to synchronize stats collecting */ + int stats_state; +#define STATS_STATE_DISABLE 0 +#define STATS_STATE_ENABLE 1 +#define STATS_STATE_STOP 2 /* stop stats on next iteration */ + + /* used by dmae command loader */ + struct dmae_command dmae; + int executer_idx; + + u32 old_brb_discard; + struct bmac_stats old_bmac; + struct tstorm_per_client_stats old_tclient; + struct z_stream_s *strm; + void *gunzip_buf; + dma_addr_t gunzip_mapping; + int gunzip_outlen; +#define FW_BUF_SIZE 0x8000 + +}; + + +/* DMAE command defines */ +#define DMAE_CMD_SRC_PCI 0 +#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC + +#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT) + +#define DMAE_CMD_C_DST_PCI 0 +#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT) + +#define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE + +#define DMAE_CMD_ENDIANITY_NO_SWAP (0 << DMAE_COMMAND_ENDIANITY_SHIFT) +#define DMAE_CMD_ENDIANITY_B_SWAP (1 << DMAE_COMMAND_ENDIANITY_SHIFT) +#define DMAE_CMD_ENDIANITY_DW_SWAP (2 << DMAE_COMMAND_ENDIANITY_SHIFT) +#define DMAE_CMD_ENDIANITY_B_DW_SWAP (3 << DMAE_COMMAND_ENDIANITY_SHIFT) + +#define DMAE_CMD_PORT_0 0 +#define DMAE_CMD_PORT_1 DMAE_COMMAND_PORT + +#define DMAE_CMD_SRC_RESET DMAE_COMMAND_SRC_RESET +#define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET + +#define DMAE_LEN32_MAX 0x400 + + +/* MC hsi */ +#define RX_COPY_THRESH 92 +#define BCM_PAGE_BITS 12 +#define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS) + +#define NUM_TX_RINGS 16 +#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_tx_bd)) +#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) +#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 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) +#define TX_BD_POFF(x) ((x) & MAX_TX_DESC_CNT) + +/* The RX BD ring is special, each bd is 8 bytes but the last one is 16 */ +#define NUM_RX_RINGS 8 +#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd)) +#define MAX_RX_DESC_CNT (RX_DESC_CNT - 2) +#define RX_DESC_MASK (RX_DESC_CNT - 1) +#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 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) + +#define NUM_RCQ_RINGS (NUM_RX_RINGS * 2) +#define RCQ_DESC_CNT (BCM_PAGE_SIZE / sizeof(union eth_rx_cqe)) +#define MAX_RCQ_DESC_CNT (RCQ_DESC_CNT - 1) +#define NUM_RCQ_BD (RCQ_DESC_CNT * NUM_RCQ_RINGS) +#define MAX_RCQ_BD (NUM_RCQ_BD - 1) +#define MAX_RCQ_AVAIL (MAX_RCQ_DESC_CNT * NUM_RCQ_RINGS - 2) +#define NEXT_RCQ_IDX(x) ((((x) & MAX_RCQ_DESC_CNT) == \ + (MAX_RCQ_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) +#define RCQ_BD(x) ((x) & MAX_RCQ_BD) + + +/* used on a CID received from the HW */ +#define SW_CID(x) (le32_to_cpu(x) & \ + (COMMON_RAMROD_ETH_RX_CQE_CID >> 1)) +#define CQE_CMD(x) (le32_to_cpu(x) >> \ + COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT) + +#define BD_UNMAP_ADDR(bd) HILO_U64(le32_to_cpu((bd)->addr_hi), \ + le32_to_cpu((bd)->addr_lo)) +#define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes)) + + +#define STROM_ASSERT_ARRAY_SIZE 50 + + +#define MDIO_INDIRECT_REG_ADDR 0x1f +#define MDIO_SET_REG_BANK(bp, reg_bank) \ + bnx2x_mdio22_write(bp, MDIO_INDIRECT_REG_ADDR, reg_bank) + +#define MDIO_ACCESS_TIMEOUT 1000 + + +/* must be used on a CID before placing it on a HW ring */ +#define HW_CID(bp, x) (x | (bp->port << 23)) + +#define SP_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_spe)) +#define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) + +#define ATTN_NIG_FOR_FUNC (1L << 8) +#define ATTN_SW_TIMER_4_FUNC (1L << 9) +#define GPIO_2_FUNC (1L << 10) +#define GPIO_3_FUNC (1L << 11) +#define GPIO_4_FUNC (1L << 12) +#define ATTN_GENERAL_ATTN_1 (1L << 13) +#define ATTN_GENERAL_ATTN_2 (1L << 14) +#define ATTN_GENERAL_ATTN_3 (1L << 15) +#define ATTN_GENERAL_ATTN_4 (1L << 13) +#define ATTN_GENERAL_ATTN_5 (1L << 14) +#define ATTN_GENERAL_ATTN_6 (1L << 15) + +#define ATTN_HARD_WIRED_MASK 0xff00 +#define ATTENTION_ID 4 + + +#define BNX2X_BTR 3 +#define MAX_SPQ_PENDING 8 + + +#define BNX2X_NUM_STATS 31 +#define BNX2X_NUM_TESTS 2 + + +#define DPM_TRIGER_TYPE 0x40 +#define DOORBELL(bp, cid, val) \ + do { \ + writel((u32)val, (bp)->doorbells + (BCM_PAGE_SIZE * cid) + \ + DPM_TRIGER_TYPE); \ + } while (0) + + +/* stuff added to make the code fit 80Col */ + +#define TPA_TYPE_START ETH_FAST_PATH_RX_CQE_START_FLG +#define TPA_TYPE_END ETH_FAST_PATH_RX_CQE_END_FLG +#define TPA_TYPE(cqe) (cqe->fast_path_cqe.error_type_flags & \ + (TPA_TYPE_START | TPA_TYPE_END)) +#define BNX2X_RX_SUM_OK(cqe) \ + (!(cqe->fast_path_cqe.status_flags & \ + (ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG | \ + ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG))) + +#define BNX2X_RX_SUM_FIX(cqe) \ + ((le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & \ + PARSING_FLAGS_OVER_ETHERNET_PROTOCOL) == \ + (1 << PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT)) + + +#define MDIO_AN_CL73_OR_37_COMPLETE \ + (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \ + MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE) + +#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \ + MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE +#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \ + MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE +#define GP_STATUS_SPEED_MASK \ + MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK +#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M +#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M +#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G +#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G +#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G +#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G +#define GP_STATUS_10G_HIG \ + MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG +#define GP_STATUS_10G_CX4 \ + MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 +#define GP_STATUS_12G_HIG \ + MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG +#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G +#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G +#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G +#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G +#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX +#define GP_STATUS_10G_KX4 \ + MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 + +#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD +#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD +#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD +#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4 +#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD +#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD +#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD +#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD +#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD +#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD +#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD +#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD +#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD +#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD +#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD +#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD +#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD +#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD +#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD +#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD +#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD +#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD +#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD + +#define NIG_STATUS_INTERRUPT_XGXS0_LINK10G \ + NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G +#define NIG_XGXS0_LINK_STATUS \ + NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS +#define NIG_XGXS0_LINK_STATUS_SIZE \ + NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE +#define NIG_SERDES0_LINK_STATUS \ + NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS +#define NIG_MASK_MI_INT \ + NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT +#define NIG_MASK_XGXS0_LINK10G \ + NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G +#define NIG_MASK_XGXS0_LINK_STATUS \ + NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS +#define NIG_MASK_SERDES0_LINK_STATUS \ + NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS + +#define XGXS_RESET_BITS \ + (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB) + +#define SERDES_RESET_BITS \ + (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \ + MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD) + + +#define BNX2X_MC_ASSERT_BITS \ + (GENERAL_ATTEN_OFFSET(TSTORM_FATAL_ASSERT_ATTENTION_BIT) | \ + GENERAL_ATTEN_OFFSET(USTORM_FATAL_ASSERT_ATTENTION_BIT) | \ + GENERAL_ATTEN_OFFSET(CSTORM_FATAL_ASSERT_ATTENTION_BIT) | \ + GENERAL_ATTEN_OFFSET(XSTORM_FATAL_ASSERT_ATTENTION_BIT)) + +#define BNX2X_MCP_ASSERT \ + GENERAL_ATTEN_OFFSET(MCP_FATAL_ASSERT_ATTENTION_BIT) + +#define BNX2X_DOORQ_ASSERT \ + AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT + +#define HW_INTERRUT_ASSERT_SET_0 \ + (AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT) +#define HW_PRTY_ASSERT_SET_0 (AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR) +#define HW_INTERRUT_ASSERT_SET_1 \ + (AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT) +#define HW_PRTY_ASSERT_SET_1 (AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR) +#define HW_INTERRUT_ASSERT_SET_2 \ + (AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT | \ + AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT |\ + AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT) +#define HW_PRTY_ASSERT_SET_2 (AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR |\ + AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR | \ + AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR) + + +#define ETH_RX_ERROR_FALGS (ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG | \ + ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG | \ + ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG) + + +#define MULTI_FLAGS \ + (TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY | \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY | \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY | \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY | \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE) + +#define MULTI_MASK 0x7f + + +#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS +#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS +#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH + +#define BNX2X_RX_SB_INDEX \ + &fp->status_blk->u_status_block.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] + +#define BNX2X_SP_DSB_INDEX \ +&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX] + + +#define CAM_IS_INVALID(x) \ +(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) + +#define CAM_INVALIDATE(x) \ +x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE + + +/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ + +#endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x_fw_defs.h b/drivers/net/bnx2x_fw_defs.h new file mode 100644 index 0000000..62a6eb8 --- /dev/null +++ b/drivers/net/bnx2x_fw_defs.h @@ -0,0 +1,198 @@ +/* bnx2x_fw_defs.h: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + */ + + +#define CSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\ + (0x1922 + (port * 0x40) + (index * 0x4)) +#define CSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\ + (0x1900 + (port * 0x40)) +#define CSTORM_HC_BTR_OFFSET(port)\ + (0x1984 + (port * 0xc0)) +#define CSTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\ + (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4)) +#define CSTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\ + (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4)) +#define CSTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\ + (0x1400 + (port * 0x280) + (cpu_id * 0x28)) +#define CSTORM_STATS_FLAGS_OFFSET(port) (0x5108 + (port * 0x8)) +#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id)\ + (0x1510 + (port * 0x240) + (client_id * 0x20)) +#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\ + (0x138a + (port * 0x28) + (index * 0x4)) +#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\ + (0x1370 + (port * 0x28)) +#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\ + (0x4b70 + (port * 0x8)) +#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function)\ + (0x1418 + (function * 0x30)) +#define TSTORM_HC_BTR_OFFSET(port)\ + (0x13c4 + (port * 0x18)) +#define TSTORM_INDIRECTION_TABLE_OFFSET(port)\ + (0x22c8 + (port * 0x80)) +#define TSTORM_INDIRECTION_TABLE_SIZE 0x80 +#define TSTORM_MAC_FILTER_CONFIG_OFFSET(port)\ + (0x1420 + (port * 0x30)) +#define TSTORM_RCQ_PROD_OFFSET(port, client_id)\ + (0x1508 + (port * 0x240) + (client_id * 0x20)) +#define TSTORM_STATS_FLAGS_OFFSET(port) (0x4b90 + (port * 0x8)) +#define USTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\ + (0x191a + (port * 0x28) + (index * 0x4)) +#define USTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\ + (0x1900 + (port * 0x28)) +#define USTORM_HC_BTR_OFFSET(port)\ + (0x1954 + (port * 0xb8)) +#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(port)\ + (0x5408 + (port * 0x8)) +#define USTORM_SB_HC_DISABLE_OFFSET(port, cpu_id, index)\ + (0x141a + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4)) +#define USTORM_SB_HC_TIMEOUT_OFFSET(port, cpu_id, index)\ + (0x1418 + (port * 0x280) + (cpu_id * 0x28) + (index * 0x4)) +#define USTORM_SB_HOST_SB_ADDR_OFFSET(port, cpu_id)\ + (0x1400 + (port * 0x280) + (cpu_id * 0x28)) +#define XSTORM_ASSERT_LIST_INDEX_OFFSET 0x1000 +#define XSTORM_ASSERT_LIST_OFFSET(idx) (0x1020 + (idx * 0x10)) +#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(port, index)\ + (0x141a + (port * 0x28) + (index * 0x4)) +#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(port)\ + (0x1400 + (port * 0x28)) +#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(port)\ + (0x5408 + (port * 0x8)) +#define XSTORM_HC_BTR_OFFSET(port)\ + (0x1454 + (port * 0x18)) +#define XSTORM_SPQ_PAGE_BASE_OFFSET(port)\ + (0x5328 + (port * 0x18)) +#define XSTORM_SPQ_PROD_OFFSET(port)\ + (0x5330 + (port * 0x18)) +#define XSTORM_STATS_FLAGS_OFFSET(port) (0x53f8 + (port * 0x8)) +#define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 + +/** +* This file defines HSI constatnts for the ETH flow +*/ + +/* hash types */ +#define DEFAULT_HASH_TYPE 0 +#define IPV4_HASH_TYPE 1 +#define TCP_IPV4_HASH_TYPE 2 +#define IPV6_HASH_TYPE 3 +#define TCP_IPV6_HASH_TYPE 4 + +/* 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) + + +/* command values for set mac command */ +#define T_ETH_MAC_COMMAND_SET 0 +#define T_ETH_MAC_COMMAND_INVALIDATE 1 + +#define T_ETH_INDIRECTION_TABLE_SIZE 128 + +/* Maximal L2 clients supported */ +#define ETH_MAX_RX_CLIENTS (18) + +/** +* This file defines HSI constatnts common to all microcode flows +*/ + +/* Connection types */ +#define ETH_CONNECTION_TYPE 0 + +#define PROTOCOL_STATE_BIT_OFFSET 6 + +#define ETH_STATE (ETH_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) + +/* microcode fixed page page size 4K (chains and ring segments) */ +#define MC_PAGE_SIZE (4096) + +/* Host coalescing constants */ + +/* IGU constants */ +#define IGU_PORT_BASE 0x0400 + +#define IGU_ADDR_MSIX 0x0000 +#define IGU_ADDR_INT_ACK 0x0200 +#define IGU_ADDR_PROD_UPD 0x0201 +#define IGU_ADDR_ATTN_BITS_UPD 0x0202 +#define IGU_ADDR_ATTN_BITS_SET 0x0203 +#define IGU_ADDR_ATTN_BITS_CLR 0x0204 +#define IGU_ADDR_COALESCE_NOW 0x0205 +#define IGU_ADDR_SIMD_MASK 0x0206 +#define IGU_ADDR_SIMD_NOMASK 0x0207 +#define IGU_ADDR_MSI_CTL 0x0210 +#define IGU_ADDR_MSI_ADDR_LO 0x0211 +#define IGU_ADDR_MSI_ADDR_HI 0x0212 +#define IGU_ADDR_MSI_DATA 0x0213 + +#define IGU_INT_ENABLE 0 +#define IGU_INT_DISABLE 1 +#define IGU_INT_NOP 2 +#define IGU_INT_NOP2 3 + +/* index numbers */ +#define HC_USTORM_DEF_SB_NUM_INDICES 4 +#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 counterto update */ + +#define HC_INDEX_U_ETH_RX_CQ_CONS 1 + +#define HC_INDEX_C_ETH_TX_CQ_CONS 1 + +#define HC_INDEX_DEF_X_SPQ_CONS 0 + +#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2 +#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3 + +/* used by the driver to get the SB offset */ +#define USTORM_ID 0 +#define CSTORM_ID 1 +#define XSTORM_ID 2 +#define TSTORM_ID 3 +#define ATTENTION_ID 4 + +/* max number of slow path commands per port */ +#define MAX_RAMRODS_PER_PORT (8) + +/* values for RX ETH CQE type field */ +#define RX_ETH_CQE_TYPE_ETH_FASTPATH (0) +#define RX_ETH_CQE_TYPE_ETH_RAMROD (1) + +/* MAC address list size */ +#define T_MAC_ADDRESS_LIST_SIZE (96) + +#define XSTORM_IP_ID_ROLL_HALF 0x8000 +#define XSTORM_IP_ID_ROLL_ALL 0 + +#define FW_LOG_LIST_SIZE (50) + +#define NUM_OF_PROTOCOLS 4 +#define MAX_COS_NUMBER 16 +#define MAX_T_STAT_COUNTER_ID 18 + +#define T_FAIR 1 +#define FAIR_MEM 2 +#define RS_PERIODIC_TIMEOUT_IN_SDM_TICS 25 + +#define UNKNOWN_ADDRESS 0 +#define UNICAST_ADDRESS 1 +#define MULTICAST_ADDRESS 2 +#define BROADCAST_ADDRESS 3 + diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h new file mode 100644 index 0000000..6fd959c --- /dev/null +++ b/drivers/net/bnx2x_hsi.h @@ -0,0 +1,2176 @@ +/* bnx2x_hsi.h: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + */ + + +#define FUNC_0 0 +#define FUNC_1 1 +#define FUNC_MAX 2 + + +/* This value (in milliseconds) determines the frequency of the driver + * issuing the PULSE message code. The firmware monitors this periodic + * pulse to determine when to switch to an OS-absent mode. */ +#define DRV_PULSE_PERIOD_MS 250 + +/* This value (in milliseconds) determines how long the driver should + * wait for an acknowledgement from the firmware before timing out. Once + * the firmware has timed out, the driver will assume there is no firmware + * running and there won't be any firmware-driver synchronization during a + * driver reset. */ +#define FW_ACK_TIME_OUT_MS 5000 + +#define FW_ACK_POLL_TIME_MS 1 + +#define FW_ACK_NUM_OF_POLL (FW_ACK_TIME_OUT_MS/FW_ACK_POLL_TIME_MS) + +/* LED Blink rate that will achieve ~15.9Hz */ +#define LED_BLINK_RATE_VAL 480 + +/**************************************************************************** + * Driver <-> FW Mailbox * + ****************************************************************************/ +struct drv_fw_mb { + u32 drv_mb_header; +#define DRV_MSG_CODE_MASK 0xffff0000 +#define DRV_MSG_CODE_LOAD_REQ 0x10000000 +#define DRV_MSG_CODE_LOAD_DONE 0x11000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_EN 0x20000000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS 0x20010000 +#define DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP 0x20020000 +#define DRV_MSG_CODE_UNLOAD_DONE 0x21000000 +#define DRV_MSG_CODE_DIAG_ENTER_REQ 0x50000000 +#define DRV_MSG_CODE_DIAG_EXIT_REQ 0x60000000 +#define DRV_MSG_CODE_VALIDATE_KEY 0x70000000 +#define DRV_MSG_CODE_GET_CURR_KEY 0x80000000 +#define DRV_MSG_CODE_GET_UPGRADE_KEY 0x81000000 +#define DRV_MSG_CODE_GET_MANUF_KEY 0x82000000 +#define DRV_MSG_CODE_LOAD_L2B_PRAM 0x90000000 + +#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 drv_mb_param; + + u32 fw_mb_header; +#define FW_MSG_CODE_MASK 0xffff0000 +#define FW_MSG_CODE_DRV_LOAD_COMMON 0x11000000 +#define FW_MSG_CODE_DRV_LOAD_PORT 0x12000000 +#define FW_MSG_CODE_DRV_LOAD_REFUSED 0x13000000 +#define FW_MSG_CODE_DRV_LOAD_DONE 0x14000000 +#define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x21000000 +#define FW_MSG_CODE_DRV_UNLOAD_PORT 0x22000000 +#define FW_MSG_CODE_DRV_UNLOAD_DONE 0x23000000 +#define FW_MSG_CODE_DIAG_ENTER_DONE 0x50000000 +#define FW_MSG_CODE_DIAG_REFUSE 0x51000000 +#define FW_MSG_CODE_VALIDATE_KEY_SUCCESS 0x70000000 +#define FW_MSG_CODE_VALIDATE_KEY_FAILURE 0x71000000 +#define FW_MSG_CODE_GET_KEY_DONE 0x80000000 +#define FW_MSG_CODE_NO_KEY 0x8f000000 +#define FW_MSG_CODE_LIC_INFO_NOT_READY 0x8f800000 +#define FW_MSG_CODE_L2B_PRAM_LOADED 0x90000000 +#define FW_MSG_CODE_L2B_PRAM_T_LOAD_FAILURE 0x91000000 +#define FW_MSG_CODE_L2B_PRAM_C_LOAD_FAILURE 0x92000000 +#define FW_MSG_CODE_L2B_PRAM_X_LOAD_FAILURE 0x93000000 +#define FW_MSG_CODE_L2B_PRAM_U_LOAD_FAILURE 0x94000000 + +#define FW_MSG_SEQ_NUMBER_MASK 0x0000ffff + + u32 fw_mb_param; + + u32 link_status; + /* Driver should update this field on any link change event */ + +#define LINK_STATUS_LINK_FLAG_MASK 0x00000001 +#define LINK_STATUS_LINK_UP 0x00000001 +#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001E +#define LINK_STATUS_SPEED_AND_DUPLEX_AN_NOT_COMPLETE (0<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10THD (1<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10TFD (2<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXHD (3<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100T4 (4<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100TXFD (5<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (6<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000XFD (7<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500THD (8<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500TFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_2500XFD (9<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GTFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10GXFD (10<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GTFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12GXFD (11<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD (12<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GTFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_13GXFD (13<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GTFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_15GXFD (14<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GTFD (15<<1) +#define LINK_STATUS_SPEED_AND_DUPLEX_16GXFD (15<<1) + +#define LINK_STATUS_AUTO_NEGOTIATE_FLAG_MASK 0x00000020 +#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 + +#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 +#define LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK 0x00000080 +#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 + +#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 +#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 +#define LINK_STATUS_LINK_PARTNER_100T4_CAPABLE 0x00000800 +#define LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE 0x00001000 +#define LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE 0x00002000 +#define LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE 0x00004000 +#define LINK_STATUS_LINK_PARTNER_10THD_CAPABLE 0x00008000 + +#define LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK 0x00010000 +#define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00010000 + +#define LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK 0x00020000 +#define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00020000 + +#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 +#define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0<<18) +#define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1<<18) +#define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2<<18) +#define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3<<18) + +#define LINK_STATUS_SERDES_LINK 0x00100000 + +#define LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE 0x00200000 +#define LINK_STATUS_LINK_PARTNER_2500XHD_CAPABLE 0x00400000 +#define LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE 0x00800000 +#define LINK_STATUS_LINK_PARTNER_12GXFD_CAPABLE 0x01000000 +#define LINK_STATUS_LINK_PARTNER_12_5GXFD_CAPABLE 0x02000000 +#define LINK_STATUS_LINK_PARTNER_13GXFD_CAPABLE 0x04000000 +#define LINK_STATUS_LINK_PARTNER_15GXFD_CAPABLE 0x08000000 +#define LINK_STATUS_LINK_PARTNER_16GXFD_CAPABLE 0x10000000 + + u32 drv_pulse_mb; +#define DRV_PULSE_SEQ_MASK 0x00007fff +#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 + /* The system time is in the format of + * (year-2001)*12*32 + month*32 + day. */ +#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicate to the firmware not to go into the + * OS-absent when it is not getting driver pulse. + * This is used for debugging as well for PXE(MBA). */ + + u32 mcp_pulse_mb; +#define MCP_PULSE_SEQ_MASK 0x00007fff +#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 + /* Indicates to the driver not to assert due to lack + * of MCP response */ +#define MCP_EVENT_MASK 0xffff0000 +#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 + +}; + + +/**************************************************************************** + * Shared HW configuration * + ****************************************************************************/ +struct shared_hw_cfg { /* NVRAM Offset */ + /* Up to 16 bytes of NULL-terminated string */ + u8 part_num[16]; /* 0x104 */ + + u32 config; /* 0x114 */ +#define SHARED_HW_CFG_MDIO_VOLTAGE_MASK 0x00000001 +#define SHARED_HW_CFG_MDIO_VOLTAGE_SHIFT 0 +#define SHARED_HW_CFG_MDIO_VOLTAGE_1_2V 0x00000000 +#define SHARED_HW_CFG_MDIO_VOLTAGE_2_5V 0x00000001 +#define SHARED_HW_CFG_MCP_RST_ON_CORE_RST_EN 0x00000002 + +#define SHARED_HW_CFG_PORT_SWAP 0x00000004 + +#define SHARED_HW_CFG_BEACON_WOL_EN 0x00000008 + +#define SHARED_HW_CFG_MFW_SELECT_MASK 0x00000700 +#define SHARED_HW_CFG_MFW_SELECT_SHIFT 8 + /* Whatever MFW found in NVM + (if multiple found, priority order is: NC-SI, UMP, IPMI) */ +#define SHARED_HW_CFG_MFW_SELECT_DEFAULT 0x00000000 +#define SHARED_HW_CFG_MFW_SELECT_NC_SI 0x00000100 +#define SHARED_HW_CFG_MFW_SELECT_UMP 0x00000200 +#define SHARED_HW_CFG_MFW_SELECT_IPMI 0x00000300 + /* Use SPIO4 as an arbiter between: 0-NC_SI, 1-IPMI + (can only be used when an add-in board, not BMC, pulls-down SPIO4) */ +#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_IPMI 0x00000400 + /* Use SPIO4 as an arbiter between: 0-UMP, 1-IPMI + (can only be used when an add-in board, not BMC, pulls-down SPIO4) */ +#define SHARED_HW_CFG_MFW_SELECT_SPIO4_UMP_IPMI 0x00000500 + /* Use SPIO4 as an arbiter between: 0-NC-SI, 1-UMP + (can only be used when an add-in board, not BMC, pulls-down SPIO4) */ +#define SHARED_HW_CFG_MFW_SELECT_SPIO4_NC_SI_UMP 0x00000600 + +#define SHARED_HW_CFG_LED_MODE_MASK 0x000f0000 +#define SHARED_HW_CFG_LED_MODE_SHIFT 16 +#define SHARED_HW_CFG_LED_MAC1 0x00000000 +#define SHARED_HW_CFG_LED_PHY1 0x00010000 +#define SHARED_HW_CFG_LED_PHY2 0x00020000 +#define SHARED_HW_CFG_LED_PHY3 0x00030000 +#define SHARED_HW_CFG_LED_MAC2 0x00040000 +#define SHARED_HW_CFG_LED_PHY4 0x00050000 +#define SHARED_HW_CFG_LED_PHY5 0x00060000 +#define SHARED_HW_CFG_LED_PHY6 0x00070000 +#define SHARED_HW_CFG_LED_MAC3 0x00080000 +#define SHARED_HW_CFG_LED_PHY7 0x00090000 +#define SHARED_HW_CFG_LED_PHY9 0x000a0000 +#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_AN_ENABLE_MASK 0x3f000000 +#define SHARED_HW_CFG_AN_ENABLE_SHIFT 24 +#define SHARED_HW_CFG_AN_ENABLE_CL37 0x01000000 +#define SHARED_HW_CFG_AN_ENABLE_CL73 0x02000000 +#define SHARED_HW_CFG_AN_ENABLE_BAM 0x04000000 +#define SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION 0x08000000 +#define SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT 0x10000000 +#define SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY 0x20000000 + + u32 config2; /* 0x118 */ + /* one time auto detect grace period (in sec) */ +#define SHARED_HW_CFG_GRACE_PERIOD_MASK 0x000000ff +#define SHARED_HW_CFG_GRACE_PERIOD_SHIFT 0 + +#define SHARED_HW_CFG_PCIE_GEN2_ENABLED 0x00000100 + + /* The default value for the core clock is 250MHz and it is + achieved by setting the clock change to 4 */ +#define SHARED_HW_CFG_CLOCK_CHANGE_MASK 0x00000e00 +#define SHARED_HW_CFG_CLOCK_CHANGE_SHIFT 9 + +#define SHARED_HW_CFG_SMBUS_TIMING_100KHZ 0x00000000 +#define SHARED_HW_CFG_SMBUS_TIMING_400KHZ 0x00001000 + +#define SHARED_HW_CFG_HIDE_FUNC1 0x00002000 + + u32 power_dissipated; /* 0x11c */ +#define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000 +#define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24 + +#define SHARED_HW_CFG_POWER_MGNT_SCALE_MASK 0x00ff0000 +#define SHARED_HW_CFG_POWER_MGNT_SCALE_SHIFT 16 +#define SHARED_HW_CFG_POWER_MGNT_UNKNOWN_SCALE 0x00000000 +#define SHARED_HW_CFG_POWER_MGNT_DOT_1_WATT 0x00010000 +#define SHARED_HW_CFG_POWER_MGNT_DOT_01_WATT 0x00020000 +#define SHARED_HW_CFG_POWER_MGNT_DOT_001_WATT 0x00030000 + + u32 ump_nc_si_config; /* 0x120 */ +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MASK 0x00000003 +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_SHIFT 0 +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MAC 0x00000000 +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_PHY 0x00000001 +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_MII 0x00000000 +#define SHARED_HW_CFG_UMP_NC_SI_MII_MODE_RMII 0x00000002 + +#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_MASK 0x00000f00 +#define SHARED_HW_CFG_UMP_NC_SI_NUM_DEVS_SHIFT 8 + +#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_MASK 0x00ff0000 +#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_SHIFT 16 +#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_NONE 0x00000000 +#define SHARED_HW_CFG_UMP_NC_SI_EXT_PHY_TYPE_BCM5221 0x00010000 + + u32 board; /* 0x124 */ +#define SHARED_HW_CFG_BOARD_TYPE_MASK 0x0000ffff +#define SHARED_HW_CFG_BOARD_TYPE_SHIFT 0 +#define SHARED_HW_CFG_BOARD_TYPE_NONE 0x00000000 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1000 0x00000001 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1001 0x00000002 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1002G 0x00000003 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1004G 0x00000004 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1007G 0x00000005 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1015G 0x00000006 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710A1020G 0x00000007 +#define SHARED_HW_CFG_BOARD_TYPE_BCM957710T1003G 0x00000008 + +#define SHARED_HW_CFG_BOARD_VER_MASK 0xffff0000 +#define SHARED_HW_CFG_BOARD_VER_SHIFT 16 +#define SHARED_HW_CFG_BOARD_MAJOR_VER_MASK 0xf0000000 +#define SHARED_HW_CFG_BOARD_MAJOR_VER_SHIFT 28 +#define SHARED_HW_CFG_BOARD_MINOR_VER_MASK 0x0f000000 +#define SHARED_HW_CFG_BOARD_MINOR_VER_SHIFT 24 +#define SHARED_HW_CFG_BOARD_REV_MASK 0x00ff0000 +#define SHARED_HW_CFG_BOARD_REV_SHIFT 16 + + u32 reserved; /* 0x128 */ + +}; + +/**************************************************************************** + * Port HW configuration * + ****************************************************************************/ +struct port_hw_cfg { /* function 0: 0x12c-0x2bb, function 1: 0x2bc-0x44b */ + + /* Fields below are port specific (in anticipation of dual port + devices */ + u32 pci_id; +#define PORT_HW_CFG_PCI_VENDOR_ID_MASK 0xffff0000 +#define PORT_HW_CFG_PCI_DEVICE_ID_MASK 0x0000ffff + + u32 pci_sub_id; +#define PORT_HW_CFG_PCI_SUBSYS_DEVICE_ID_MASK 0xffff0000 +#define PORT_HW_CFG_PCI_SUBSYS_VENDOR_ID_MASK 0x0000ffff + + u32 power_dissipated; +#define PORT_HW_CFG_POWER_DIS_D3_MASK 0xff000000 +#define PORT_HW_CFG_POWER_DIS_D3_SHIFT 24 +#define PORT_HW_CFG_POWER_DIS_D2_MASK 0x00ff0000 +#define PORT_HW_CFG_POWER_DIS_D2_SHIFT 16 +#define PORT_HW_CFG_POWER_DIS_D1_MASK 0x0000ff00 +#define PORT_HW_CFG_POWER_DIS_D1_SHIFT 8 +#define PORT_HW_CFG_POWER_DIS_D0_MASK 0x000000ff +#define PORT_HW_CFG_POWER_DIS_D0_SHIFT 0 + + u32 power_consumed; +#define PORT_HW_CFG_POWER_CONS_D3_MASK 0xff000000 +#define PORT_HW_CFG_POWER_CONS_D3_SHIFT 24 +#define PORT_HW_CFG_POWER_CONS_D2_MASK 0x00ff0000 +#define PORT_HW_CFG_POWER_CONS_D2_SHIFT 16 +#define PORT_HW_CFG_POWER_CONS_D1_MASK 0x0000ff00 +#define PORT_HW_CFG_POWER_CONS_D1_SHIFT 8 +#define PORT_HW_CFG_POWER_CONS_D0_MASK 0x000000ff +#define PORT_HW_CFG_POWER_CONS_D0_SHIFT 0 + + u32 mac_upper; +#define PORT_HW_CFG_UPPERMAC_MASK 0x0000ffff +#define PORT_HW_CFG_UPPERMAC_SHIFT 0 + u32 mac_lower; + + u32 iscsi_mac_upper; /* Upper 16 bits are always zeroes */ + u32 iscsi_mac_lower; + + u32 rdma_mac_upper; /* Upper 16 bits are always zeroes */ + u32 rdma_mac_lower; + + u32 serdes_config; + /* for external PHY, or forced mode or during AN */ +#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000 +#define PORT_HW_CFG_SERDES_TX_DRV_PRE_EMPHASIS_SHIFT 16 + +#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK 0x0000ffff +#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 0 + + u16 serdes_tx_driver_pre_emphasis[16]; + u16 serdes_rx_driver_equalizer[16]; + + u32 xgxs_config_lane0; + u32 xgxs_config_lane1; + u32 xgxs_config_lane2; + u32 xgxs_config_lane3; + /* for external PHY, or forced mode or during AN */ +#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_MASK 0xffff0000 +#define PORT_HW_CFG_XGXS_TX_DRV_PRE_EMPHASIS_SHIFT 16 + +#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_MASK 0x0000ffff +#define PORT_HW_CFG_XGXS_RX_DRV_EQUALIZER_SHIFT 0 + + u16 xgxs_tx_driver_pre_emphasis_lane0[16]; + u16 xgxs_tx_driver_pre_emphasis_lane1[16]; + u16 xgxs_tx_driver_pre_emphasis_lane2[16]; + u16 xgxs_tx_driver_pre_emphasis_lane3[16]; + + u16 xgxs_rx_driver_equalizer_lane0[16]; + u16 xgxs_rx_driver_equalizer_lane1[16]; + u16 xgxs_rx_driver_equalizer_lane2[16]; + u16 xgxs_rx_driver_equalizer_lane3[16]; + + 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 +#define PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT 8 +#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK 0x0000c000 +#define PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT 14 + /* AN and forced */ +#define PORT_HW_CFG_LANE_SWAP_CFG_01230123 0x00001b1b + /* forced only */ +#define PORT_HW_CFG_LANE_SWAP_CFG_01233210 0x00001be4 + /* forced only */ +#define PORT_HW_CFG_LANE_SWAP_CFG_31203120 0x0000d8d8 + /* forced only */ +#define PORT_HW_CFG_LANE_SWAP_CFG_32103210 0x0000e4e4 + + u32 external_phy_config; +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK 0xff000000 +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_SHIFT 24 +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT 0x00000000 +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482 0x01000000 +#define PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN 0xff000000 + +#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK 0x00ff0000 +#define PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT 16 + +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK 0x0000ff00 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SHIFT 8 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT 0x00000000 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8071 0x00000100 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072 0x00000200 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN 0x0000ff00 + +#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK 0x000000ff +#define PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT 0 + + u32 speed_capability_mask; +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_MASK 0xffff0000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_SHIFT 16 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL 0x00010000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF 0x00020000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF 0x00040000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL 0x00080000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_1G 0x00100000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G 0x00200000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_10G 0x00400000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12G 0x00800000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_12_5G 0x01000000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_13G 0x02000000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_15G 0x04000000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_16G 0x08000000 +#define PORT_HW_CFG_SPEED_CAPABILITY_D0_RESERVED 0xf0000000 + +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_MASK 0x0000ffff +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_SHIFT 0 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_FULL 0x00000001 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10M_HALF 0x00000002 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_HALF 0x00000004 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_100M_FULL 0x00000008 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_1G 0x00000010 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_2_5G 0x00000020 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_10G 0x00000040 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12G 0x00000080 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_12_5G 0x00000100 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_13G 0x00000200 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_15G 0x00000400 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_16G 0x00000800 +#define PORT_HW_CFG_SPEED_CAPABILITY_D3_RESERVED 0x0000f000 + + u32 reserved[2]; + +}; + +/**************************************************************************** + * Shared Feature configuration * + ****************************************************************************/ +struct shared_feat_cfg { /* NVRAM Offset */ + u32 bmc_common; /* 0x450 */ +#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001 + +}; + + +/**************************************************************************** + * Port Feature configuration * + ****************************************************************************/ +struct port_feat_cfg { /* function 0: 0x454-0x4c7, function 1: 0x4c8-0x53b */ + u32 config; +#define PORT_FEATURE_BAR1_SIZE_MASK 0x0000000f +#define PORT_FEATURE_BAR1_SIZE_SHIFT 0 +#define PORT_FEATURE_BAR1_SIZE_DISABLED 0x00000000 +#define PORT_FEATURE_BAR1_SIZE_64K 0x00000001 +#define PORT_FEATURE_BAR1_SIZE_128K 0x00000002 +#define PORT_FEATURE_BAR1_SIZE_256K 0x00000003 +#define PORT_FEATURE_BAR1_SIZE_512K 0x00000004 +#define PORT_FEATURE_BAR1_SIZE_1M 0x00000005 +#define PORT_FEATURE_BAR1_SIZE_2M 0x00000006 +#define PORT_FEATURE_BAR1_SIZE_4M 0x00000007 +#define PORT_FEATURE_BAR1_SIZE_8M 0x00000008 +#define PORT_FEATURE_BAR1_SIZE_16M 0x00000009 +#define PORT_FEATURE_BAR1_SIZE_32M 0x0000000a +#define PORT_FEATURE_BAR1_SIZE_64M 0x0000000b +#define PORT_FEATURE_BAR1_SIZE_128M 0x0000000c +#define PORT_FEATURE_BAR1_SIZE_256M 0x0000000d +#define PORT_FEATURE_BAR1_SIZE_512M 0x0000000e +#define PORT_FEATURE_BAR1_SIZE_1G 0x0000000f +#define PORT_FEATURE_BAR2_SIZE_MASK 0x000000f0 +#define PORT_FEATURE_BAR2_SIZE_SHIFT 4 +#define PORT_FEATURE_BAR2_SIZE_DISABLED 0x00000000 +#define PORT_FEATURE_BAR2_SIZE_64K 0x00000010 +#define PORT_FEATURE_BAR2_SIZE_128K 0x00000020 +#define PORT_FEATURE_BAR2_SIZE_256K 0x00000030 +#define PORT_FEATURE_BAR2_SIZE_512K 0x00000040 +#define PORT_FEATURE_BAR2_SIZE_1M 0x00000050 +#define PORT_FEATURE_BAR2_SIZE_2M 0x00000060 +#define PORT_FEATURE_BAR2_SIZE_4M 0x00000070 +#define PORT_FEATURE_BAR2_SIZE_8M 0x00000080 +#define PORT_FEATURE_BAR2_SIZE_16M 0x00000090 +#define PORT_FEATURE_BAR2_SIZE_32M 0x000000a0 +#define PORT_FEATURE_BAR2_SIZE_64M 0x000000b0 +#define PORT_FEATURE_BAR2_SIZE_128M 0x000000c0 +#define PORT_FEATURE_BAR2_SIZE_256M 0x000000d0 +#define PORT_FEATURE_BAR2_SIZE_512M 0x000000e0 +#define PORT_FEATURE_BAR2_SIZE_1G 0x000000f0 +#define PORT_FEATURE_EN_SIZE_MASK 0x07000000 +#define PORT_FEATURE_EN_SIZE_SHIFT 24 +#define PORT_FEATURE_WOL_ENABLED 0x01000000 +#define PORT_FEATURE_MBA_ENABLED 0x02000000 +#define PORT_FEATURE_MFW_ENABLED 0x04000000 + + u32 wol_config; + /* Default is used when driver sets to "auto" mode */ +#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003 +#define PORT_FEATURE_WOL_DEFAULT_SHIFT 0 +#define PORT_FEATURE_WOL_DEFAULT_DISABLE 0x00000000 +#define PORT_FEATURE_WOL_DEFAULT_MAGIC 0x00000001 +#define PORT_FEATURE_WOL_DEFAULT_ACPI 0x00000002 +#define PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI 0x00000003 +#define PORT_FEATURE_WOL_RES_PAUSE_CAP 0x00000004 +#define PORT_FEATURE_WOL_RES_ASYM_PAUSE_CAP 0x00000008 +#define PORT_FEATURE_WOL_ACPI_UPON_MGMT 0x00000010 + + u32 mba_config; +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK 0x00000003 +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT 0 +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE 0x00000000 +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL 0x00000001 +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP 0x00000002 +#define PORT_FEATURE_MBA_BOOT_AGENT_TYPE_ISCSIB 0x00000003 +#define PORT_FEATURE_MBA_RES_PAUSE_CAP 0x00000100 +#define PORT_FEATURE_MBA_RES_ASYM_PAUSE_CAP 0x00000200 +#define PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x00000400 +#define PORT_FEATURE_MBA_HOTKEY_CTRL_S 0x00000000 +#define PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x00000800 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK 0x000ff000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT 12 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED 0x00000000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2K 0x00001000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4K 0x00002000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8K 0x00003000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16K 0x00004000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32K 0x00005000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_64K 0x00006000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_128K 0x00007000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_256K 0x00008000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_512K 0x00009000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_1M 0x0000a000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_2M 0x0000b000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_4M 0x0000c000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_8M 0x0000d000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_16M 0x0000e000 +#define PORT_FEATURE_MBA_EXP_ROM_SIZE_32M 0x0000f000 +#define PORT_FEATURE_MBA_MSG_TIMEOUT_MASK 0x00f00000 +#define PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT 20 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK 0x03000000 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT 24 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO 0x00000000 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS 0x01000000 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H 0x02000000 +#define PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H 0x03000000 +#define PORT_FEATURE_MBA_LINK_SPEED_MASK 0x3c000000 +#define PORT_FEATURE_MBA_LINK_SPEED_SHIFT 26 +#define PORT_FEATURE_MBA_LINK_SPEED_AUTO 0x00000000 +#define PORT_FEATURE_MBA_LINK_SPEED_10HD 0x04000000 +#define PORT_FEATURE_MBA_LINK_SPEED_10FD 0x08000000 +#define PORT_FEATURE_MBA_LINK_SPEED_100HD 0x0c000000 +#define PORT_FEATURE_MBA_LINK_SPEED_100FD 0x10000000 +#define PORT_FEATURE_MBA_LINK_SPEED_1GBPS 0x14000000 +#define PORT_FEATURE_MBA_LINK_SPEED_2_5GBPS 0x18000000 +#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_CX4 0x1c000000 +#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KX4 0x20000000 +#define PORT_FEATURE_MBA_LINK_SPEED_10GBPS_KR 0x24000000 +#define PORT_FEATURE_MBA_LINK_SPEED_12GBPS 0x28000000 +#define PORT_FEATURE_MBA_LINK_SPEED_12_5GBPS 0x2c000000 +#define PORT_FEATURE_MBA_LINK_SPEED_13GBPS 0x30000000 +#define PORT_FEATURE_MBA_LINK_SPEED_15GBPS 0x34000000 +#define PORT_FEATURE_MBA_LINK_SPEED_16GBPS 0x38000000 + + u32 bmc_config; +#define PORT_FEATURE_BMC_LINK_OVERRIDE_DEFAULT 0x00000000 +#define PORT_FEATURE_BMC_LINK_OVERRIDE_EN 0x00000001 + + u32 mba_vlan_cfg; +#define PORT_FEATURE_MBA_VLAN_TAG_MASK 0x0000ffff +#define PORT_FEATURE_MBA_VLAN_TAG_SHIFT 0 +#define PORT_FEATURE_MBA_VLAN_EN 0x00010000 + + u32 resource_cfg; +#define PORT_FEATURE_RESOURCE_CFG_VALID 0x00000001 +#define PORT_FEATURE_RESOURCE_CFG_DIAG 0x00000002 +#define PORT_FEATURE_RESOURCE_CFG_L2 0x00000004 +#define PORT_FEATURE_RESOURCE_CFG_ISCSI 0x00000008 +#define PORT_FEATURE_RESOURCE_CFG_RDMA 0x00000010 + + u32 smbus_config; + /* Obsolete */ +#define PORT_FEATURE_SMBUS_EN 0x00000001 +#define PORT_FEATURE_SMBUS_ADDR_MASK 0x000000fe +#define PORT_FEATURE_SMBUS_ADDR_SHIFT 1 + + u32 iscsib_boot_cfg; +#define PORT_FEATURE_ISCSIB_SKIP_TARGET_BOOT 0x00000001 + + u32 link_config; /* Used as HW defaults for the driver */ +#define PORT_FEATURE_CONNECTED_SWITCH_MASK 0x03000000 +#define PORT_FEATURE_CONNECTED_SWITCH_SHIFT 24 + /* (forced) low speed switch (< 10G) */ +#define PORT_FEATURE_CON_SWITCH_1G_SWITCH 0x00000000 + /* (forced) high speed switch (>= 10G) */ +#define PORT_FEATURE_CON_SWITCH_10G_SWITCH 0x01000000 +#define PORT_FEATURE_CON_SWITCH_AUTO_DETECT 0x02000000 +#define PORT_FEATURE_CON_SWITCH_ONE_TIME_DETECT 0x03000000 + +#define PORT_FEATURE_LINK_SPEED_MASK 0x000f0000 +#define PORT_FEATURE_LINK_SPEED_SHIFT 16 +#define PORT_FEATURE_LINK_SPEED_AUTO 0x00000000 +#define PORT_FEATURE_LINK_SPEED_10M_FULL 0x00010000 +#define PORT_FEATURE_LINK_SPEED_10M_HALF 0x00020000 +#define PORT_FEATURE_LINK_SPEED_100M_HALF 0x00030000 +#define PORT_FEATURE_LINK_SPEED_100M_FULL 0x00040000 +#define PORT_FEATURE_LINK_SPEED_1G 0x00050000 +#define PORT_FEATURE_LINK_SPEED_2_5G 0x00060000 +#define PORT_FEATURE_LINK_SPEED_10G_CX4 0x00070000 +#define PORT_FEATURE_LINK_SPEED_10G_KX4 0x00080000 +#define PORT_FEATURE_LINK_SPEED_10G_KR 0x00090000 +#define PORT_FEATURE_LINK_SPEED_12G 0x000a0000 +#define PORT_FEATURE_LINK_SPEED_12_5G 0x000b0000 +#define PORT_FEATURE_LINK_SPEED_13G 0x000c0000 +#define PORT_FEATURE_LINK_SPEED_15G 0x000d0000 +#define PORT_FEATURE_LINK_SPEED_16G 0x000e0000 + +#define PORT_FEATURE_FLOW_CONTROL_MASK 0x00000700 +#define PORT_FEATURE_FLOW_CONTROL_SHIFT 8 +#define PORT_FEATURE_FLOW_CONTROL_AUTO 0x00000000 +#define PORT_FEATURE_FLOW_CONTROL_TX 0x00000100 +#define PORT_FEATURE_FLOW_CONTROL_RX 0x00000200 +#define PORT_FEATURE_FLOW_CONTROL_BOTH 0x00000300 +#define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 + + /* The default for MCP link configuration, + uses the same defines as link_config */ + u32 mfw_wol_link_cfg; + + u32 reserved[19]; + +}; + + +/**************************************************************************** + * Device Information * + ****************************************************************************/ +struct dev_info { /* size */ + + u32 bc_rev; /* 8 bits each: major, minor, build */ /* 4 */ + + struct shared_hw_cfg shared_hw_config; /* 40 */ + + struct port_hw_cfg port_hw_config[FUNC_MAX]; /* 400*2=800 */ + + struct shared_feat_cfg shared_feature_config; /* 4 */ + + struct port_feat_cfg port_feature_config[FUNC_MAX];/* 116*2=232 */ + +}; + + +/**************************************************************************** + * Management firmware state * + ****************************************************************************/ +/* Allocate 320 bytes for management firmware: still not known exactly + * how much IMD needs. */ +#define MGMTFW_STATE_WORD_SIZE 80 + +struct mgmtfw_state { + u32 opaque[MGMTFW_STATE_WORD_SIZE]; +}; + + +/**************************************************************************** + * Shared Memory Region * + ****************************************************************************/ +struct shmem_region { /* SharedMem Offset (size) */ + u32 validity_map[FUNC_MAX]; /* 0x0 (4 * 2 = 0x8) */ +#define SHR_MEM_VALIDITY_PCI_CFG 0x00000001 +#define SHR_MEM_VALIDITY_MB 0x00000002 +#define SHR_MEM_VALIDITY_DEV_INFO 0x00000004 + /* One licensing bit should be set */ +#define SHR_MEM_VALIDITY_LIC_KEY_IN_EFFECT_MASK 0x00000038 +#define SHR_MEM_VALIDITY_LIC_MANUF_KEY_IN_EFFECT 0x00000008 +#define SHR_MEM_VALIDITY_LIC_UPGRADE_KEY_IN_EFFECT 0x00000010 +#define SHR_MEM_VALIDITY_LIC_NO_KEY_IN_EFFECT 0x00000020 + + struct drv_fw_mb drv_fw_mb[FUNC_MAX]; /* 0x8 (28 * 2 = 0x38) */ + + struct dev_info dev_info; /* 0x40 (0x438) */ + +#ifdef _LICENSE_H + license_key_t drv_lic_key[FUNC_MAX]; /* 0x478 (52 * 2 = 0x68) */ +#else /* Linux! */ + u8 reserved[52*FUNC_MAX]; +#endif + + /* FW information (for internal FW use) */ + u32 fw_info_fio_offset; /* 0x4e0 (0x4) */ + struct mgmtfw_state mgmtfw_state; /* 0x4e4 (0x140) */ + +}; /* 0x624 */ + + +#define BCM_5710_FW_MAJOR_VERSION 4 +#define BCM_5710_FW_MINOR_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 14 +#define BCM_5710_FW_COMPILE_FLAGS 1 + + +/* + * attention bits + */ +struct atten_def_status_block { + u32 attn_bits; + u32 attn_bits_ack; +#if defined(__BIG_ENDIAN) + u16 attn_bits_index; + u8 reserved0; + u8 status_block_id; +#elif defined(__LITTLE_ENDIAN) + u8 status_block_id; + u8 reserved0; + u16 attn_bits_index; +#endif + u32 reserved1; +}; + + +/* + * common data for all protocols + */ +struct doorbell_hdr { + u8 header; +#define DOORBELL_HDR_RX (0x1<<0) +#define DOORBELL_HDR_RX_SHIFT 0 +#define DOORBELL_HDR_DB_TYPE (0x1<<1) +#define DOORBELL_HDR_DB_TYPE_SHIFT 1 +#define DOORBELL_HDR_DPM_SIZE (0x3<<2) +#define DOORBELL_HDR_DPM_SIZE_SHIFT 2 +#define DOORBELL_HDR_CONN_TYPE (0xF<<4) +#define DOORBELL_HDR_CONN_TYPE_SHIFT 4 +}; + +/* + * doorbell message send to the chip + */ +struct doorbell { +#if defined(__BIG_ENDIAN) + u16 zero_fill2; + u8 zero_fill1; + struct doorbell_hdr header; +#elif defined(__LITTLE_ENDIAN) + struct doorbell_hdr header; + u8 zero_fill1; + u16 zero_fill2; +#endif +}; + + +/* + * IGU driver acknowlegement register + */ +struct igu_ack_register { +#if defined(__BIG_ENDIAN) + u16 sb_id_and_flags; +#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0) +#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0 +#define IGU_ACK_REGISTER_STORM_ID (0x7<<5) +#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5 +#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8) +#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8 +#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9) +#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9 +#define IGU_ACK_REGISTER_RESERVED (0x1F<<11) +#define IGU_ACK_REGISTER_RESERVED_SHIFT 11 + u16 status_block_index; +#elif defined(__LITTLE_ENDIAN) + u16 status_block_index; + u16 sb_id_and_flags; +#define IGU_ACK_REGISTER_STATUS_BLOCK_ID (0x1F<<0) +#define IGU_ACK_REGISTER_STATUS_BLOCK_ID_SHIFT 0 +#define IGU_ACK_REGISTER_STORM_ID (0x7<<5) +#define IGU_ACK_REGISTER_STORM_ID_SHIFT 5 +#define IGU_ACK_REGISTER_UPDATE_INDEX (0x1<<8) +#define IGU_ACK_REGISTER_UPDATE_INDEX_SHIFT 8 +#define IGU_ACK_REGISTER_INTERRUPT_MODE (0x3<<9) +#define IGU_ACK_REGISTER_INTERRUPT_MODE_SHIFT 9 +#define IGU_ACK_REGISTER_RESERVED (0x1F<<11) +#define IGU_ACK_REGISTER_RESERVED_SHIFT 11 +#endif +}; + + +/* + * Parser parsing flags field + */ +struct parsing_flags { + u16 flags; +#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE (0x1<<0) +#define PARSING_FLAGS_ETHERNET_ADDRESS_TYPE_SHIFT 0 +#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS (0x3<<1) +#define PARSING_FLAGS_NUMBER_OF_NESTED_VLANS_SHIFT 1 +#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL (0x3<<3) +#define PARSING_FLAGS_OVER_ETHERNET_PROTOCOL_SHIFT 3 +#define PARSING_FLAGS_IP_OPTIONS (0x1<<5) +#define PARSING_FLAGS_IP_OPTIONS_SHIFT 5 +#define PARSING_FLAGS_FRAGMENTATION_STATUS (0x1<<6) +#define PARSING_FLAGS_FRAGMENTATION_STATUS_SHIFT 6 +#define PARSING_FLAGS_OVER_IP_PROTOCOL (0x3<<7) +#define PARSING_FLAGS_OVER_IP_PROTOCOL_SHIFT 7 +#define PARSING_FLAGS_PURE_ACK_INDICATION (0x1<<9) +#define PARSING_FLAGS_PURE_ACK_INDICATION_SHIFT 9 +#define PARSING_FLAGS_TCP_OPTIONS_EXIST (0x1<<10) +#define PARSING_FLAGS_TCP_OPTIONS_EXIST_SHIFT 10 +#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG (0x1<<11) +#define PARSING_FLAGS_TIME_STAMP_EXIST_FLAG_SHIFT 11 +#define PARSING_FLAGS_CONNECTION_MATCH (0x1<<12) +#define PARSING_FLAGS_CONNECTION_MATCH_SHIFT 12 +#define PARSING_FLAGS_LLC_SNAP (0x1<<13) +#define PARSING_FLAGS_LLC_SNAP_SHIFT 13 +#define PARSING_FLAGS_RESERVED0 (0x3<<14) +#define PARSING_FLAGS_RESERVED0_SHIFT 14 +}; + + +/* + * dmae command structure + */ +struct dmae_command { + u32 opcode; +#define DMAE_COMMAND_SRC (0x1<<0) +#define DMAE_COMMAND_SRC_SHIFT 0 +#define DMAE_COMMAND_DST (0x3<<1) +#define DMAE_COMMAND_DST_SHIFT 1 +#define DMAE_COMMAND_C_DST (0x1<<3) +#define DMAE_COMMAND_C_DST_SHIFT 3 +#define DMAE_COMMAND_C_TYPE_ENABLE (0x1<<4) +#define DMAE_COMMAND_C_TYPE_ENABLE_SHIFT 4 +#define DMAE_COMMAND_C_TYPE_CRC_ENABLE (0x1<<5) +#define DMAE_COMMAND_C_TYPE_CRC_ENABLE_SHIFT 5 +#define DMAE_COMMAND_C_TYPE_CRC_OFFSET (0x7<<6) +#define DMAE_COMMAND_C_TYPE_CRC_OFFSET_SHIFT 6 +#define DMAE_COMMAND_ENDIANITY (0x3<<9) +#define DMAE_COMMAND_ENDIANITY_SHIFT 9 +#define DMAE_COMMAND_PORT (0x1<<11) +#define DMAE_COMMAND_PORT_SHIFT 11 +#define DMAE_COMMAND_CRC_RESET (0x1<<12) +#define DMAE_COMMAND_CRC_RESET_SHIFT 12 +#define DMAE_COMMAND_SRC_RESET (0x1<<13) +#define DMAE_COMMAND_SRC_RESET_SHIFT 13 +#define DMAE_COMMAND_DST_RESET (0x1<<14) +#define DMAE_COMMAND_DST_RESET_SHIFT 14 +#define DMAE_COMMAND_RESERVED0 (0x1FFFF<<15) +#define DMAE_COMMAND_RESERVED0_SHIFT 15 + u32 src_addr_lo; + u32 src_addr_hi; + u32 dst_addr_lo; + u32 dst_addr_hi; +#if defined(__BIG_ENDIAN) + u16 reserved1; + u16 len; +#elif defined(__LITTLE_ENDIAN) + u16 len; + u16 reserved1; +#endif + u32 comp_addr_lo; + u32 comp_addr_hi; + u32 comp_val; + u32 crc32; + u32 crc32_c; +#if defined(__BIG_ENDIAN) + u16 crc16_c; + u16 crc16; +#elif defined(__LITTLE_ENDIAN) + u16 crc16; + u16 crc16_c; +#endif +#if defined(__BIG_ENDIAN) + u16 reserved2; + u16 crc_t10; +#elif defined(__LITTLE_ENDIAN) + u16 crc_t10; + u16 reserved2; +#endif +#if defined(__BIG_ENDIAN) + u16 xsum8; + u16 xsum16; +#elif defined(__LITTLE_ENDIAN) + u16 xsum16; + u16 xsum8; +#endif +}; + + +struct double_regpair { + u32 regpair0_lo; + u32 regpair0_hi; + u32 regpair1_lo; + u32 regpair1_hi; +}; + + +/* + * The eth Rx Buffer Descriptor + */ +struct eth_rx_bd { + u32 addr_lo; + u32 addr_hi; +}; + +/* + * The eth storm context of Ustorm + */ +struct ustorm_eth_st_context { +#if defined(__BIG_ENDIAN) + u8 sb_index_number; + u8 status_block_id; + u8 __local_rx_bd_cons; + u8 __local_rx_bd_prod; +#elif defined(__LITTLE_ENDIAN) + u8 __local_rx_bd_prod; + u8 __local_rx_bd_cons; + u8 status_block_id; + u8 sb_index_number; +#endif +#if defined(__BIG_ENDIAN) + u16 rcq_cons; + u16 rx_bd_cons; +#elif defined(__LITTLE_ENDIAN) + u16 rx_bd_cons; + u16 rcq_cons; +#endif + u32 rx_bd_page_base_lo; + u32 rx_bd_page_base_hi; + u32 rcq_base_address_lo; + u32 rcq_base_address_hi; +#if defined(__BIG_ENDIAN) + u16 __num_of_returned_cqes; + u8 num_rss; + u8 flags; +#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0) +#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0 +#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1) +#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1 +#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2) +#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2 +#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3) +#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3 +#elif defined(__LITTLE_ENDIAN) + u8 flags; +#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT (0x1<<0) +#define USTORM_ETH_ST_CONTEXT_ENABLE_MC_ALIGNMENT_SHIFT 0 +#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC (0x1<<1) +#define USTORM_ETH_ST_CONTEXT_ENABLE_DYNAMIC_HC_SHIFT 1 +#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA (0x1<<2) +#define USTORM_ETH_ST_CONTEXT_ENABLE_TPA_SHIFT 2 +#define __USTORM_ETH_ST_CONTEXT_RESERVED0 (0x1F<<3) +#define __USTORM_ETH_ST_CONTEXT_RESERVED0_SHIFT 3 + u8 num_rss; + u16 __num_of_returned_cqes; +#endif +#if defined(__BIG_ENDIAN) + u16 mc_alignment_size; + u16 agg_threshold; +#elif defined(__LITTLE_ENDIAN) + u16 agg_threshold; + u16 mc_alignment_size; +#endif + struct eth_rx_bd __local_bd_ring[16]; +}; + +/* + * The eth storm context of Tstorm + */ +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 __agg_misc7; +#elif defined(__LITTLE_ENDIAN) + u8 __agg_misc7; + u8 __reserved2; + u16 __reserved3; +#endif +}; + +/* + * The eth aggregative context of Xstorm + */ +struct xstorm_eth_ag_context { +#if defined(__BIG_ENDIAN) + u16 __bd_prod; + u8 __agg_vars1; + u8 __state; +#elif defined(__LITTLE_ENDIAN) + u8 __state; + u8 __agg_vars1; + u16 __bd_prod; +#endif +#if defined(__BIG_ENDIAN) + u8 cdu_reserved; + u8 __agg_vars4; + u8 __agg_vars3; + u8 __agg_vars2; +#elif defined(__LITTLE_ENDIAN) + u8 __agg_vars2; + u8 __agg_vars3; + u8 __agg_vars4; + u8 cdu_reserved; +#endif + u32 __more_packets_to_send; +#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 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; +}; + +/* + * 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; +}; + +/* + * 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 +}; + +/* + * 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 +#if defined(__BIG_ENDIAN) + u8 cdu_usage; + u8 __agg_misc2; + u16 __agg_misc1; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_misc1; + u8 __agg_misc2; + 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 +}; + +/* + * Timers connection context + */ +struct timers_block_context { + u32 __reserved_0; + u32 __reserved_1; + u32 __reserved_2; + u32 __reserved_flags; +}; + +/* + * structure for easy accessability to assembler + */ +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_TCP_CSUM (0x1<<2) +#define ETH_TX_BD_FLAGS_TCP_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_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_SW_LSO (0x1<<6) +#define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 +#define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) +#define ETH_TX_BD_FLAGS_IPV6_SHIFT 7 +}; + +/* + * The eth Tx Buffer Descriptor + */ +struct eth_tx_bd { + u32 addr_lo; + u32 addr_hi; + u16 nbd; + u16 nbytes; + u16 vlan; + struct eth_tx_bd_flags bd_flags; + u8 general_data; +#define ETH_TX_BD_HDR_NBDS (0x3F<<0) +#define ETH_TX_BD_HDR_NBDS_SHIFT 0 +#define ETH_TX_BD_ETH_ADDR_TYPE (0x3<<6) +#define ETH_TX_BD_ETH_ADDR_TYPE_SHIFT 6 +}; + +/* + * Tx parsing BD structure for ETH,Relevant in START + */ +struct eth_tx_parse_bd { + 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_CS_ANY_FLG (0x1<<4) +#define ETH_TX_PARSE_BD_CS_ANY_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 + 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; + s8 cs_offset; + u16 total_hlen; + u16 lso_mss; + u16 tcp_pseudo_csum; + u16 ip_id; + u32 tcp_send_seq; +}; + +/* + * The last BD in the BD memory will hold a pointer to the next BD memory + */ +struct eth_tx_next_bd { + u32 addr_lo; + u32 addr_hi; + u8 reserved[8]; +}; + +/* + * union for 3 Bd types + */ +union eth_tx_bd_types { + struct eth_tx_bd reg_bd; + struct eth_tx_parse_bd parse_bd; + 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 __reserved0; + u8 __local_tx_bd_prod; +#elif defined(__LITTLE_ENDIAN) + u8 __local_tx_bd_prod; + u8 __reserved0; + u16 tx_bd_cons; +#endif + u32 db_data_addr_lo; + u32 db_data_addr_hi; + u32 __pkt_cons; + u32 __gso_next; + u32 is_eth_conn_1b; + union eth_tx_bd_types __bds[13]; +}; + +/* + * 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]; +}; + +/* + * Ethernet connection context + */ +struct eth_context { + struct ustorm_eth_st_context ustorm_st_context; + struct tstorm_eth_st_context tstorm_st_context; + struct xstorm_eth_ag_context xstorm_ag_context; + struct tstorm_eth_ag_context tstorm_ag_context; + struct cstorm_eth_ag_context cstorm_ag_context; + struct ustorm_eth_ag_context ustorm_ag_context; + struct timers_block_context timers_context; + struct xstorm_eth_st_context xstorm_st_context; + struct cstorm_eth_st_context cstorm_st_context; +}; + + +/* + * ethernet doorbell + */ +struct eth_tx_doorbell { +#if defined(__BIG_ENDIAN) + u16 npackets; + u8 params; +#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) +#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 +#define ETH_TX_DOORBELL_SPARE (0x1<<7) +#define ETH_TX_DOORBELL_SPARE_SHIFT 7 + struct doorbell_hdr hdr; +#elif defined(__LITTLE_ENDIAN) + struct doorbell_hdr hdr; + u8 params; +#define ETH_TX_DOORBELL_NUM_BDS (0x3F<<0) +#define ETH_TX_DOORBELL_NUM_BDS_SHIFT 0 +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG (0x1<<6) +#define ETH_TX_DOORBELL_RESERVED_TX_FIN_FLAG_SHIFT 6 +#define ETH_TX_DOORBELL_SPARE (0x1<<7) +#define ETH_TX_DOORBELL_SPARE_SHIFT 7 + u16 npackets; +#endif +}; + + +/* + * ustorm status block + */ +struct ustorm_def_status_block { + u16 index_values[HC_USTORM_DEF_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * cstorm status block + */ +struct cstorm_def_status_block { + u16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * xstorm status block + */ +struct xstorm_def_status_block { + u16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * tstorm status block + */ +struct tstorm_def_status_block { + u16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * host status block + */ +struct host_def_status_block { + struct atten_def_status_block atten_status_block; + struct ustorm_def_status_block u_def_status_block; + struct cstorm_def_status_block c_def_status_block; + struct xstorm_def_status_block x_def_status_block; + struct tstorm_def_status_block t_def_status_block; +}; + + +/* + * ustorm status block + */ +struct ustorm_status_block { + u16 index_values[HC_USTORM_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * cstorm status block + */ +struct cstorm_status_block { + u16 index_values[HC_CSTORM_SB_NUM_INDICES]; + u16 status_block_index; + u8 reserved0; + u8 status_block_id; + u32 __flags; +}; + +/* + * host status block + */ +struct host_status_block { + struct ustorm_status_block u_status_block; + struct cstorm_status_block c_status_block; +}; + + +/* + * The data for RSS setup ramrod + */ +struct eth_client_setup_ramrod_data { + u32 client_id_5b; + u8 is_rdma_1b; + u8 reserved0; + u16 reserved1; +}; + + +/* + * L2 dynamic host coalescing init parameters + */ +struct eth_dynamic_hc_config { + u32 threshold[3]; + u8 hc_timeout[4]; +}; + + +/* + * regular eth FP CQE parameters struct + */ +struct eth_fast_path_rx_cqe { + u8 type; + u8 error_type_flags; +#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG (0x1<<0) +#define ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG_SHIFT 0 +#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG (0x1<<1) +#define ETH_FAST_PATH_RX_CQE_IP_BAD_XSUM_FLG_SHIFT 1 +#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG (0x1<<2) +#define ETH_FAST_PATH_RX_CQE_L4_BAD_XSUM_FLG_SHIFT 2 +#define ETH_FAST_PATH_RX_CQE_START_FLG (0x1<<3) +#define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 3 +#define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<4) +#define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 4 +#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x7<<5) +#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 5 + 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 +#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG (0x1<<3) +#define ETH_FAST_PATH_RX_CQE_RSS_HASH_FLG_SHIFT 3 +#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG (0x1<<4) +#define ETH_FAST_PATH_RX_CQE_BROADCAST_FLG_SHIFT 4 +#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG (0x1<<5) +#define ETH_FAST_PATH_RX_CQE_MAC_MATCH_FLG_SHIFT 5 +#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG (0x1<<6) +#define ETH_FAST_PATH_RX_CQE_IP_XSUM_NO_VALIDATION_FLG_SHIFT 6 +#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG (0x1<<7) +#define ETH_FAST_PATH_RX_CQE_L4_XSUM_NO_VALIDATION_FLG_SHIFT 7 + u8 placement_offset; + u32 rss_hash_result; + u16 vlan_tag; + u16 pkt_len; + u16 queue_index; + struct parsing_flags pars_flags; +}; + + +/* + * The data for RSS setup ramrod + */ +struct eth_halt_ramrod_data { + u32 client_id_5b; + u32 reserved0; +}; + + +/* + * Place holder for ramrods protocol specific data + */ +struct ramrod_data { + u32 data_lo; + u32 data_hi; +}; + +/* + * union for ramrod data for ethernet protocol (CQE) (force size of 16 bits) + */ +union eth_ramrod_data { + struct ramrod_data general; +}; + + +/* + * Rx Last BD in page (in ETH) + */ +struct eth_rx_bd_next_page { + u32 addr_lo; + u32 addr_hi; + u8 reserved[8]; +}; + + +/* + * Eth Rx Cqe structure- general structure for ramrods + */ +struct common_ramrod_eth_rx_cqe { + u8 type; + u8 conn_type_3b; + u16 reserved; + u32 conn_and_cmd_data; +#define COMMON_RAMROD_ETH_RX_CQE_CID (0xFFFFFF<<0) +#define COMMON_RAMROD_ETH_RX_CQE_CID_SHIFT 0 +#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID (0xFF<<24) +#define COMMON_RAMROD_ETH_RX_CQE_CMD_ID_SHIFT 24 + struct ramrod_data protocol_data; +}; + +/* + * Rx Last CQE in page (in ETH) + */ +struct eth_rx_cqe_next_page { + u32 addr_lo; + u32 addr_hi; + u32 reserved0; + u32 reserved1; +}; + +/* + * union for all eth rx cqe types (fix their sizes) + */ +union eth_rx_cqe { + struct eth_fast_path_rx_cqe fast_path_cqe; + struct common_ramrod_eth_rx_cqe ramrod_cqe; + struct eth_rx_cqe_next_page next_page_cqe; +}; + + +/* + * common data for all protocols + */ +struct spe_hdr { + u32 conn_and_cmd_data; +#define SPE_HDR_CID (0xFFFFFF<<0) +#define SPE_HDR_CID_SHIFT 0 +#define SPE_HDR_CMD_ID (0xFF<<24) +#define SPE_HDR_CMD_ID_SHIFT 24 + u16 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 + u16 reserved; +}; + +struct regpair { + u32 lo; + u32 hi; +}; + +/* + * ethernet slow path element + */ +union eth_specific_data { + u8 protocol_data[8]; + struct regpair mac_config_addr; + struct eth_client_setup_ramrod_data client_setup_ramrod_data; + struct eth_halt_ramrod_data halt_ramrod_data; + struct regpair leading_cqe_addr; + struct regpair update_data_addr; +}; + +/* + * ethernet slow path element + */ +struct eth_spe { + struct spe_hdr hdr; + union eth_specific_data data; +}; + + +/* + * doorbell data in host memory + */ +struct eth_tx_db_data { + u32 packets_prod; + u16 bds_prod; + u16 reserved; +}; + + +/* + * Common configuration parameters per port in Tstorm + */ +struct tstorm_eth_function_common_config { + u32 config_flags; +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY_SHIFT 0 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY (0x1<<1) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY_SHIFT 1 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY (0x1<<2) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY_SHIFT 2 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY (0x1<<3) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE (0x1<<4) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_ENABLE_SHIFT 4 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<5) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 5 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x3FFFFFF<<6) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 6 +#if defined(__BIG_ENDIAN) + u16 __secondary_vlan_id; + u8 leading_client_id; + u8 rss_result_mask; +#elif defined(__LITTLE_ENDIAN) + u8 rss_result_mask; + u8 leading_client_id; + u16 __secondary_vlan_id; +#endif +}; + +/* + * parameters for eth update ramrod + */ +struct eth_update_ramrod_data { + struct tstorm_eth_function_common_config func_config; + u8 indirectionTable[128]; +}; + + +/* + * MAC filtering configuration command header + */ +struct mac_configuration_hdr { + u8 length_6b; + u8 offset; + u16 reserved0; + u32 reserved1; +}; + +/* + * MAC address in list for ramrod + */ +struct tstorm_cam_entry { + u16 lsb_mac_addr; + u16 middle_mac_addr; + u16 msb_mac_addr; + u16 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 client_id; + u16 vlan_id; +}; + +/* + * 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]; +}; + + +/* + * Configuration parameters per client in Tstorm + */ +struct tstorm_eth_client_config { +#if defined(__BIG_ENDIAN) + u16 statistics_counter_id; + u16 mtu; +#elif defined(__LITTLE_ENDIAN) + u16 mtu; + u16 statistics_counter_id; +#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_MAC_ERR (0x1<<2) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2 +#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3 +#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4 +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5) +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5 + u16 config_flags; +#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0) +#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0 +#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1) +#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1 +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2) +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2 +#elif defined(__LITTLE_ENDIAN) + u16 config_flags; +#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE (0x1<<0) +#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REMOVAL_ENABLE_SHIFT 0 +#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<1) +#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 1 +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0 (0x3FFF<<2) +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED0_SHIFT 2 + 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_MAC_ERR (0x1<<2) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_MAC_ERR_SHIFT 2 +#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<3) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 3 +#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<4) +#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 4 +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x7FF<<5) +#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 5 +#endif +}; + + +/* + * MAC filtering configuration parameters per port in Tstorm + */ +struct tstorm_eth_mac_filter_config { + u32 ucast_drop_all; + u32 ucast_accept_all; + u32 mcast_drop_all; + u32 mcast_accept_all; + u32 bcast_drop_all; + u32 bcast_accept_all; + u32 strict_vlan; + u32 __secondary_vlan_clients; +}; + + +struct rate_shaping_per_protocol { +#if defined(__BIG_ENDIAN) + u16 reserved0; + u16 protocol_rate; +#elif defined(__LITTLE_ENDIAN) + u16 protocol_rate; + u16 reserved0; +#endif + u32 protocol_quota; + s32 current_credit; + u32 reserved; +}; + +struct rate_shaping_vars { + struct rate_shaping_per_protocol protocol_vars[NUM_OF_PROTOCOLS]; + u32 pause_mask; + u32 periodic_stop; + u32 rs_periodic_timeout; + u32 rs_threshold; + u32 last_periodic_time; + u32 reserved; +}; + +struct fairness_per_protocol { + u32 credit_delta; + s32 fair_credit; +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 state; + u8 weight; +#elif defined(__LITTLE_ENDIAN) + u8 weight; + u8 state; + u16 reserved0; +#endif + u32 reserved1; +}; + +struct fairness_vars { + struct fairness_per_protocol protocol_vars[NUM_OF_PROTOCOLS]; + u32 upper_bound; + u32 port_rate; + u32 pause_mask; + u32 fair_threshold; +}; + +struct safc_struct { + u32 cur_pause_mask; + u32 expire_time; +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 cur_cos_types; + u8 safc_timeout_usec; +#elif defined(__LITTLE_ENDIAN) + u8 safc_timeout_usec; + u8 cur_cos_types; + u16 reserved0; +#endif + u32 reserved1; +}; + +struct demo_struct { + u8 con_number[NUM_OF_PROTOCOLS]; +#if defined(__BIG_ENDIAN) + u8 reserved1; + u8 fairness_enable; + u8 rate_shaping_enable; + u8 cmng_enable; +#elif defined(__LITTLE_ENDIAN) + u8 cmng_enable; + u8 rate_shaping_enable; + u8 fairness_enable; + u8 reserved1; +#endif +}; + +struct cmng_struct { + struct rate_shaping_vars rs_vars; + struct fairness_vars fair_vars; + struct safc_struct safc_vars; + struct demo_struct demo_vars; +}; + + +struct cos_to_protocol { + u8 mask[MAX_COS_NUMBER]; +}; + + +/* + * Common statistics collected by the Xstorm (per port) + */ +struct xstorm_common_stats { + struct regpair total_sent_bytes; + u32 total_sent_pkts; + u32 unicast_pkts_sent; + struct regpair unicast_bytes_sent; + struct regpair multicast_bytes_sent; + u32 multicast_pkts_sent; + u32 broadcast_pkts_sent; + struct regpair broadcast_bytes_sent; + struct regpair done; +}; + +/* + * Protocol-common statistics collected by the Tstorm (per client) + */ +struct tstorm_per_client_stats { + struct regpair total_rcv_bytes; + struct regpair rcv_unicast_bytes; + struct regpair rcv_broadcast_bytes; + struct regpair rcv_multicast_bytes; + struct regpair rcv_error_bytes; + u32 checksum_discard; + u32 packets_too_big_discard; + u32 total_rcv_pkts; + u32 rcv_unicast_pkts; + u32 rcv_broadcast_pkts; + u32 rcv_multicast_pkts; + u32 no_buff_discard; + u32 ttl0_discard; + u32 mac_discard; + u32 reserved; +}; + +/* + * Protocol-common statistics collected by the Tstorm (per port) + */ +struct tstorm_common_stats { + struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID]; + u32 mac_filter_discard; + u32 xxoverflow_discard; + u32 brb_truncate_discard; + u32 reserved; + struct regpair done; +}; + +/* + * Eth statistics query sturcture for the eth_stats_quesry ramrod + */ +struct eth_stats_query { + struct xstorm_common_stats xstorm_common; + struct tstorm_common_stats tstorm_common; +}; + + +/* + * FW version stored in the Xstorm RAM + */ +struct fw_version { +#if defined(__BIG_ENDIAN) + u16 patch; + u8 primary; + u8 client; +#elif defined(__LITTLE_ENDIAN) + u8 client; + u8 primary; + u16 patch; +#endif + u32 flags; +#define FW_VERSION_OPTIMIZED (0x1<<0) +#define FW_VERSION_OPTIMIZED_SHIFT 0 +#define FW_VERSION_BIG_ENDIEN (0x1<<1) +#define FW_VERSION_BIG_ENDIEN_SHIFT 1 +#define __FW_VERSION_RESERVED (0x3FFFFFFF<<2) +#define __FW_VERSION_RESERVED_SHIFT 2 +}; + + +/* + * FW version stored in first line of pram + */ +struct pram_fw_version { +#if defined(__BIG_ENDIAN) + u16 patch; + u8 primary; + u8 client; +#elif defined(__LITTLE_ENDIAN) + u8 client; + u8 primary; + u16 patch; +#endif + u8 flags; +#define PRAM_FW_VERSION_OPTIMIZED (0x1<<0) +#define PRAM_FW_VERSION_OPTIMIZED_SHIFT 0 +#define PRAM_FW_VERSION_STORM_ID (0x3<<1) +#define PRAM_FW_VERSION_STORM_ID_SHIFT 1 +#define PRAM_FW_VERSION_BIG_ENDIEN (0x1<<3) +#define PRAM_FW_VERSION_BIG_ENDIEN_SHIFT 3 +#define __PRAM_FW_VERSION_RESERVED0 (0xF<<4) +#define __PRAM_FW_VERSION_RESERVED0_SHIFT 4 +}; + + +/* + * The send queue element + */ +struct slow_path_element { + struct spe_hdr hdr; + u8 protocol_data[8]; +}; + + +/* + * eth/toe flags that indicate if to query + */ +struct stats_indication_flags { + u32 collect_eth; + u32 collect_toe; +}; + + diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h new file mode 100644 index 0000000..04f93bf --- /dev/null +++ b/drivers/net/bnx2x_init.h @@ -0,0 +1,564 @@ +/* bnx2x_init.h: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + * + * Written by: Eliezer Tamir + */ + +#ifndef BNX2X_INIT_H +#define BNX2X_INIT_H + +#define COMMON 0x1 +#define PORT0 0x2 +#define PORT1 0x4 + +#define INIT_EMULATION 0x1 +#define INIT_FPGA 0x2 +#define INIT_ASIC 0x4 +#define INIT_HARDWARE 0x7 + +#define STORM_INTMEM_SIZE (0x5800 / 4) +#define TSTORM_INTMEM_ADDR 0x1a0000 +#define CSTORM_INTMEM_ADDR 0x220000 +#define XSTORM_INTMEM_ADDR 0x2a0000 +#define USTORM_INTMEM_ADDR 0x320000 + + +/* Init operation types and structures */ + +#define OP_RD 0x1 /* read single register */ +#define OP_WR 0x2 /* write single register */ +#define OP_IW 0x3 /* write single register using mailbox */ +#define OP_SW 0x4 /* copy a string to the device */ +#define OP_SI 0x5 /* copy a string using mailbox */ +#define OP_ZR 0x6 /* clear memory */ +#define OP_ZP 0x7 /* unzip then copy with DMAE */ +#define OP_WB 0x8 /* copy a string using DMAE */ + +struct raw_op { + u32 op :8; + u32 offset :24; + u32 raw_data; +}; + +struct op_read { + u32 op :8; + u32 offset :24; + u32 pad; +}; + +struct op_write { + u32 op :8; + u32 offset :24; + u32 val; +}; + +struct op_string_write { + u32 op :8; + u32 offset :24; +#ifdef __LITTLE_ENDIAN + u16 data_off; + u16 data_len; +#else /* __BIG_ENDIAN */ + u16 data_len; + u16 data_off; +#endif +}; + +struct op_zero { + u32 op :8; + u32 offset :24; + u32 len; +}; + +union init_op { + struct op_read read; + struct op_write write; + struct op_string_write str_wr; + struct op_zero zero; + struct raw_op raw; +}; + +#include "bnx2x_init_values.h" + +static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); + +static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, + u32 dst_addr, u32 len32); + +static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len); + +static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, + u32 len) +{ + int i; + + for (i = 0; i < len; i++) { + REG_WR(bp, addr + i*4, data[i]); + if (!(i % 10000)) { + touch_softlockup_watchdog(); + cpu_relax(); + } + } +} + +#define INIT_MEM_WR(reg, data, reg_off, len) \ + bnx2x_init_str_wr(bp, reg + reg_off*4, data, len) + +static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, + u16 len) +{ + int i; + + for (i = 0; i < len; i++) { + REG_WR_IND(bp, addr + i*4, data[i]); + if (!(i % 10000)) { + touch_softlockup_watchdog(); + cpu_relax(); + } + } +} + +static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, + u32 len, int gunzip) +{ + int offset = 0; + + if (gunzip) { + int rc; +#ifdef __BIG_ENDIAN + int i, size; + u32 *temp; + + temp = kmalloc(len, GFP_KERNEL); + size = (len / 4) + ((len % 4) ? 1 : 0); + for (i = 0; i < size; i++) + temp[i] = swab32(data[i]); + data = temp; +#endif + rc = bnx2x_gunzip(bp, (u8 *)data, len); + if (rc) { + DP(NETIF_MSG_HW, "gunzip failed ! rc %d\n", rc); + return; + } + len = bp->gunzip_outlen; +#ifdef __BIG_ENDIAN + kfree(temp); + for (i = 0; i < len; i++) + ((u32 *)bp->gunzip_buf)[i] = + swab32(((u32 *)bp->gunzip_buf)[i]); +#endif + } else { + if ((len * 4) > FW_BUF_SIZE) { + BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len*4); + return; + } + memcpy(bp->gunzip_buf, data, len * 4); + } + + while (len > DMAE_LEN32_MAX) { + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, DMAE_LEN32_MAX); + offset += DMAE_LEN32_MAX * 4; + len -= DMAE_LEN32_MAX; + } + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len); +} + +#define INIT_MEM_WB(reg, data, reg_off, len) \ + bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 0) + +#define INIT_GUNZIP_DMAE(reg, data, reg_off, len) \ + bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 1) + +static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) +{ + int offset = 0; + + if ((len * 4) > FW_BUF_SIZE) { + BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len * 4); + return; + } + memset(bp->gunzip_buf, fill, len * 4); + + while (len > DMAE_LEN32_MAX) { + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, + addr + offset, DMAE_LEN32_MAX); + offset += DMAE_LEN32_MAX * 4; + len -= DMAE_LEN32_MAX; + } + bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len); +} + +static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) +{ + int i; + union init_op *op; + u32 op_type, addr, len; + const u32 *data; + + for (i = op_start; i < op_end; i++) { + + op = (union init_op *)&(init_ops[i]); + + op_type = op->str_wr.op; + addr = op->str_wr.offset; + len = op->str_wr.data_len; + data = init_data + op->str_wr.data_off; + + switch (op_type) { + case OP_RD: + REG_RD(bp, addr); + break; + case OP_WR: + REG_WR(bp, addr, op->write.val); + break; + case OP_SW: + bnx2x_init_str_wr(bp, addr, data, len); + break; + case OP_WB: + bnx2x_init_wr_wb(bp, addr, data, len, 0); + break; + case OP_SI: + bnx2x_init_ind_wr(bp, addr, data, len); + break; + case OP_ZR: + bnx2x_init_fill(bp, addr, 0, op->zero.len); + break; + case OP_ZP: + bnx2x_init_wr_wb(bp, addr, data, len, 1); + break; + default: + BNX2X_ERR("BAD init operation!\n"); + } + } +} + + +/**************************************************************************** +* PXP +****************************************************************************/ +/* + * This code configures the PCI read/write arbiter + * which implements a wighted round robin + * between the virtual queues in the chip. + * + * The values were derived for each PCI max payload and max request size. + * since max payload and max request size are only known at run time, + * this is done as a separate init stage. + */ + +#define NUM_WR_Q 13 +#define NUM_RD_Q 29 +#define MAX_RD_ORD 3 +#define MAX_WR_ORD 2 + +/* configuration for one arbiter queue */ +struct arb_line { + int l; + int add; + int ubound; +}; + +/* derived configuration for each read queue for each max request size */ +static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = { + {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} }, + {{4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4}, {4 , 8 , 4} }, + {{4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3}, {4 , 3 , 3} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {16 , 3 , 11}, {16 , 3 , 11} }, + {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25}, {64 , 64 , 41} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {64 , 3 , 41} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 3 , 6}, {16 , 3 , 11}, {32 , 3 , 21}, {32 , 3 , 21} }, + {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81}, {64 , 64 , 120} } +}; + +/* derived configuration for each write queue for each max request size */ +static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = { + {{4 , 6 , 3}, {4 , 6 , 3}, {4 , 6 , 3} }, + {{4 , 2 , 3}, {4 , 2 , 3}, {4 , 2 , 3} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {32 , 2 , 21} }, + {{8 , 64 , 25}, {16 , 64 , 25}, {32 , 64 , 25} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} }, + {{8 , 2 , 6}, {16 , 2 , 11}, {16 , 2 , 11} }, + {{8 , 9 , 6}, {16 , 9 , 11}, {32 , 9 , 21} }, + {{8 , 47 , 19}, {16 , 47 , 19}, {32 , 47 , 21} }, + {{8 , 9 , 6}, {16 , 9 , 11}, {16 , 9 , 11} }, + {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} } +}; + +/* register adresses for read queues */ +static const struct arb_line read_arb_addr[NUM_RD_Q-1] = { + {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0, + PXP2_REG_RQ_BW_RD_UBOUND0}, + {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, + PXP2_REG_PSWRQ_BW_UB1}, + {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2, + PXP2_REG_PSWRQ_BW_UB2}, + {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3, + PXP2_REG_PSWRQ_BW_UB3}, + {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4, + PXP2_REG_RQ_BW_RD_UBOUND4}, + {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5, + PXP2_REG_RQ_BW_RD_UBOUND5}, + {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6, + PXP2_REG_PSWRQ_BW_UB6}, + {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7, + PXP2_REG_PSWRQ_BW_UB7}, + {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8, + PXP2_REG_PSWRQ_BW_UB8}, + {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9, + PXP2_REG_PSWRQ_BW_UB9}, + {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10, + PXP2_REG_PSWRQ_BW_UB10}, + {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11, + PXP2_REG_PSWRQ_BW_UB11}, + {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12, + PXP2_REG_RQ_BW_RD_UBOUND12}, + {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13, + PXP2_REG_RQ_BW_RD_UBOUND13}, + {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14, + PXP2_REG_RQ_BW_RD_UBOUND14}, + {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15, + PXP2_REG_RQ_BW_RD_UBOUND15}, + {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16, + PXP2_REG_RQ_BW_RD_UBOUND16}, + {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17, + PXP2_REG_RQ_BW_RD_UBOUND17}, + {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18, + PXP2_REG_RQ_BW_RD_UBOUND18}, + {PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19, + PXP2_REG_RQ_BW_RD_UBOUND19}, + {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20, + PXP2_REG_RQ_BW_RD_UBOUND20}, + {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22, + PXP2_REG_RQ_BW_RD_UBOUND22}, + {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23, + PXP2_REG_RQ_BW_RD_UBOUND23}, + {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24, + PXP2_REG_RQ_BW_RD_UBOUND24}, + {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25, + PXP2_REG_RQ_BW_RD_UBOUND25}, + {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26, + PXP2_REG_RQ_BW_RD_UBOUND26}, + {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27, + PXP2_REG_RQ_BW_RD_UBOUND27}, + {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28, + PXP2_REG_PSWRQ_BW_UB28} +}; + +/* register adresses for wrtie queues */ +static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { + {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, + PXP2_REG_PSWRQ_BW_UB1}, + {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2, + PXP2_REG_PSWRQ_BW_UB2}, + {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3, + PXP2_REG_PSWRQ_BW_UB3}, + {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6, + PXP2_REG_PSWRQ_BW_UB6}, + {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7, + PXP2_REG_PSWRQ_BW_UB7}, + {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8, + PXP2_REG_PSWRQ_BW_UB8}, + {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9, + PXP2_REG_PSWRQ_BW_UB9}, + {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10, + PXP2_REG_PSWRQ_BW_UB10}, + {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11, + PXP2_REG_PSWRQ_BW_UB11}, + {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28, + PXP2_REG_PSWRQ_BW_UB28}, + {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29, + PXP2_REG_RQ_BW_WR_UBOUND29}, + {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30, + PXP2_REG_RQ_BW_WR_UBOUND30} +}; + +static void bnx2x_init_pxp(struct bnx2x *bp) +{ + int r_order, w_order; + u32 val, i; + + pci_read_config_word(bp->pdev, + bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val); + DP(NETIF_MSG_HW, "read 0x%x from devctl\n", val); + w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5); + r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12); + + if (r_order > MAX_RD_ORD) { + DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", + r_order, MAX_RD_ORD); + r_order = MAX_RD_ORD; + } + if (w_order > MAX_WR_ORD) { + DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n", + w_order, MAX_WR_ORD); + w_order = MAX_WR_ORD; + } + DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); + + for (i = 0; i < NUM_RD_Q-1; i++) { + REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l); + REG_WR(bp, read_arb_addr[i].add, + read_arb_data[i][r_order].add); + REG_WR(bp, read_arb_addr[i].ubound, + read_arb_data[i][r_order].ubound); + } + + for (i = 0; i < NUM_WR_Q-1; i++) { + if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) || + (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) { + + REG_WR(bp, write_arb_addr[i].l, + write_arb_data[i][w_order].l); + + REG_WR(bp, write_arb_addr[i].add, + write_arb_data[i][w_order].add); + + REG_WR(bp, write_arb_addr[i].ubound, + write_arb_data[i][w_order].ubound); + } else { + + val = REG_RD(bp, write_arb_addr[i].l); + REG_WR(bp, write_arb_addr[i].l, + val | (write_arb_data[i][w_order].l << 10)); + + val = REG_RD(bp, write_arb_addr[i].add); + REG_WR(bp, write_arb_addr[i].add, + val | (write_arb_data[i][w_order].add << 10)); + + val = REG_RD(bp, write_arb_addr[i].ubound); + REG_WR(bp, write_arb_addr[i].ubound, + val | (write_arb_data[i][w_order].ubound << 7)); + } + } + + val = write_arb_data[NUM_WR_Q-1][w_order].add; + val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10; + val += write_arb_data[NUM_WR_Q-1][w_order].l << 17; + REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val); + + val = read_arb_data[NUM_RD_Q-1][r_order].add; + val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10; + val += read_arb_data[NUM_RD_Q-1][r_order].l << 17; + REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); + + REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); + REG_WR(bp, PXP2_REG_RQ_WR_MBS0 + 8, w_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); + REG_WR(bp, PXP2_REG_RQ_RD_MBS0 + 8, r_order); + + REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16); +} + + +/**************************************************************************** +* CDU +****************************************************************************/ + +#define CDU_REGION_NUMBER_XCM_AG 2 +#define CDU_REGION_NUMBER_UCM_AG 4 + +/** + * String-to-compress [31:8] = CID (all 24 bits) + * String-to-compress [7:4] = Region + * String-to-compress [3:0] = Type + */ +#define CDU_VALID_DATA(_cid, _region, _type) \ + (((_cid) << 8) | (((_region) & 0xf) << 4) | (((_type) & 0xf))) +#define CDU_CRC8(_cid, _region, _type) \ + calc_crc8(CDU_VALID_DATA(_cid, _region, _type), 0xff) +#define CDU_RSRVD_VALUE_TYPE_A(_cid, _region, _type) \ + (0x80 | (CDU_CRC8(_cid, _region, _type) & 0x7f)) +#define CDU_RSRVD_VALUE_TYPE_B(_crc, _type) \ + (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7)) +#define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val) ((_val) & ~0x80) + +/***************************************************************************** + * Description: + * Calculates crc 8 on a word value: polynomial 0-1-2-8 + * Code was translated from Verilog. + ****************************************************************************/ +static u8 calc_crc8(u32 data, u8 crc) +{ + u8 D[32]; + u8 NewCRC[8]; + u8 C[8]; + u8 crc_res; + u8 i; + + /* split the data into 31 bits */ + for (i = 0; i < 32; i++) { + D[i] = data & 1; + data = data >> 1; + } + + /* split the crc into 8 bits */ + for (i = 0; i < 8; i++) { + C[i] = crc & 1; + crc = crc >> 1; + } + + NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^ + D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^ + C[6] ^ C[7]; + NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^ + D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^ + D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6]; + NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^ + D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^ + C[0] ^ C[1] ^ C[4] ^ C[5]; + NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^ + D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^ + C[1] ^ C[2] ^ C[5] ^ C[6]; + NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^ + D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^ + C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7]; + NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^ + D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^ + C[3] ^ C[4] ^ C[7]; + NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^ + D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^ + C[5]; + NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^ + D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^ + C[6]; + + crc_res = 0; + for (i = 0; i < 8; i++) + crc_res |= (NewCRC[i] << i); + + return crc_res; +} + + +#endif /* BNX2X_INIT_H */ + diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h new file mode 100644 index 0000000..bef0a9b --- /dev/null +++ b/drivers/net/bnx2x_init_values.h @@ -0,0 +1,6368 @@ +#ifndef __BNX2X_INIT_VALUES_H__ +#define __BNX2X_INIT_VALUES_H__ + +/* This array contains the list of operations needed to initialize the chip. + * + * For each block in the chip there are three init stages: + * common - HW used by both ports, + * port1 and port2 - initialization for a specific Ethernet port. + * When a port is opened or closed, the management CPU tells the driver + * whether to init/disable common HW in addition to the port HW. + * This way the first port going up will first initializes the common HW, + * and the last port going down also resets the common HW + * + * For each init stage/block there is a list of actions needed in a format: + * {operation, register, data} + * where: + * OP_WR - write a value to the chip. + * OP_RD - read a register (usually a clear on read register). + * OP_SW - string write, write a section of consecutive addresses to the chip. + * OP_SI - copy a string using indirect writes. + * OP_ZR - clear a range of memory. + * OP_ZP - unzip and copy using DMAE. + * OP_WB - string copy using DMAE. + * + * The #defines mark the stages. + * + */ + +static const struct raw_op init_ops[] = { +#define PRS_COMMON_START 0 + {OP_WR, PRS_REG_INC_VALUE, 0xf}, + {OP_WR, PRS_REG_EVENT_ID_1, 0x45}, + {OP_WR, PRS_REG_EVENT_ID_2, 0x84}, + {OP_WR, PRS_REG_EVENT_ID_3, 0x6}, + {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4}, + {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0}, + {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000}, + {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000}, + {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000}, + {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5}, + {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000}, + {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000}, + {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000}, + {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4}, + {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000}, + {OP_ZR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000}, + {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000}, + {OP_ZR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4}, + {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0}, + {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0}, + {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0}, + {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff}, + {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff}, + {OP_WR, PRS_REG_PURE_REGIONS, 0x3e}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f}, + {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f}, +#define PRS_COMMON_END 46 +#define PRS_PORT0_START 46 + {OP_WR, PRS_REG_CID_PORT_0, 0x0}, +#define PRS_PORT0_END 47 +#define PRS_PORT1_START 47 + {OP_WR, PRS_REG_CID_PORT_1, 0x800000}, +#define PRS_PORT1_END 48 +#define TSDM_COMMON_START 48 + {OP_WR, TSDM_REG_CFC_RSP_START_ADDR, 0x411}, + {OP_WR, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400}, + {OP_WR, TSDM_REG_Q_COUNTER_START_ADDR, 0x404}, + {OP_WR, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419}, + {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff}, + {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff}, + {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff}, + {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff}, + {OP_ZR, TSDM_REG_AGG_INT_EVENT_0, 0x80}, + {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff}, + {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f}, + {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff}, + {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf}, + {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, + {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, + {OP_WR, TSDM_REG_TIMER_TICK, 0x3e8}, +#define TSDM_COMMON_END 76 +#define TCM_COMMON_START 76 + {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20}, + {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32}, + {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020}, + {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020}, + {OP_WR, TCM_REG_TM_TCM_HDR, 0x30}, + {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000}, + {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33}, + {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30}, + {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31}, + {OP_WR, TCM_REG_PRS_WEIGHT, 0x4}, + {OP_WR, TCM_REG_PBF_WEIGHT, 0x5}, + {OP_WR, TCM_REG_CP_WEIGHT, 0x0}, + {OP_WR, TCM_REG_TSDM_WEIGHT, 0x4}, + {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1}, + {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1}, + {OP_WR, TCM_REG_GR_LD0_PR, 0x1}, + {OP_WR, TCM_REG_GR_LD1_PR, 0x2}, + {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1}, + {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40}, + {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40}, + {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20}, + {OP_WR, TCM_REG_XX_INIT_CRD, 0x13}, + {OP_WR, TCM_REG_XX_MSG_NUM, 0x20}, + {OP_ZR, TCM_REG_XX_TABLE, 0xa}, + {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000}, + {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7}, + {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7}, + {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8}, + {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8}, + {OP_ZR, TCM_REG_N_SM_CTX_LD_4, 0x4}, + {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6}, + {OP_WR, TCM_REG_PHYS_QNUM0_0, 0xd}, + {OP_WR, TCM_REG_PHYS_QNUM0_1, 0x2d}, + {OP_ZR, TCM_REG_PHYS_QNUM1_0, 0x6}, + {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1}, + {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1}, + {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1}, + {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1}, + {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1}, + {OP_WR, TCM_REG_TSDM_IFEN, 0x1}, + {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1}, + {OP_WR, TCM_REG_PRS_IFEN, 0x1}, + {OP_WR, TCM_REG_PBF_IFEN, 0x1}, + {OP_WR, TCM_REG_USEM_IFEN, 0x1}, + {OP_WR, TCM_REG_CSEM_IFEN, 0x1}, + {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1}, + {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1}, + {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1}, + {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1}, + {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1}, +#define TCM_COMMON_END 126 +#define BRB1_COMMON_START 126 + {OP_SW, BRB1_REG_LL_RAM, 0x2000020}, + {OP_WR, BRB1_REG_SOFT_RESET, 0x1}, + {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_2, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_3, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_2, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_3, 0x0}, + {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0}, + {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220}, + {OP_WR, BRB1_REG_SOFT_RESET, 0x0}, +#define BRB1_COMMON_END 139 +#define TSEM_COMMON_START 139 + {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0}, + {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0}, + {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0}, + {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0}, + {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0}, + {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0}, + {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1}, + {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2}, + {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3}, + {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0}, + {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4}, + {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1}, + {OP_WR, TSEM_REG_TS_0_AS, 0x0}, + {OP_WR, TSEM_REG_TS_1_AS, 0x1}, + {OP_WR, TSEM_REG_TS_2_AS, 0x4}, + {OP_WR, TSEM_REG_TS_3_AS, 0x0}, + {OP_WR, TSEM_REG_TS_4_AS, 0x1}, + {OP_WR, TSEM_REG_TS_5_AS, 0x3}, + {OP_WR, TSEM_REG_TS_6_AS, 0x0}, + {OP_WR, TSEM_REG_TS_7_AS, 0x1}, + {OP_WR, TSEM_REG_TS_8_AS, 0x4}, + {OP_WR, TSEM_REG_TS_9_AS, 0x0}, + {OP_WR, TSEM_REG_TS_10_AS, 0x1}, + {OP_WR, TSEM_REG_TS_11_AS, 0x3}, + {OP_WR, TSEM_REG_TS_12_AS, 0x0}, + {OP_WR, TSEM_REG_TS_13_AS, 0x1}, + {OP_WR, TSEM_REG_TS_14_AS, 0x4}, + {OP_WR, TSEM_REG_TS_15_AS, 0x0}, + {OP_WR, TSEM_REG_TS_16_AS, 0x4}, + {OP_WR, TSEM_REG_TS_17_AS, 0x3}, + {OP_ZR, TSEM_REG_TS_18_AS, 0x2}, + {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff}, + {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff}, + {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0}, + {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0}, + {OP_WR, TSEM_REG_PAS_DISABLE, 0x0}, + {OP_WR, TSEM_REG_THREADS_LIST, 0xff}, + {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, + {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2000, 0x1b3}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x2000 + 0x6cc, 0x10223}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1000, 0x2}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x810, 0x4}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1fa0, 0x4}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x4cf0, 0x80224}, + {OP_ZP, TSEM_REG_INT_TABLE, 0x8c022c}, + {OP_ZP, TSEM_REG_PRAM, 0x3395024f}, + {OP_ZP, TSEM_REG_PRAM + 0x8000, 0x2c760f35}, + {OP_ZP, TSEM_REG_PRAM + 0x10000, 0x5e1a53}, + {OP_ZP, TSEM_REG_PRAM + 0x18000, 0x5e1a6b}, + {OP_ZP, TSEM_REG_PRAM + 0x20000, 0x5e1a83}, + {OP_ZP, TSEM_REG_PRAM + 0x28000, 0x5e1a9b}, + {OP_ZP, TSEM_REG_PRAM + 0x30000, 0x5e1ab3}, + {OP_ZP, TSEM_REG_PRAM + 0x38000, 0x5e1acb}, +#define TSEM_COMMON_END 202 +#define TSEM_PORT0_START 202 + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x4000 + 0x5b0, 0x21ae3}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1370, 0xa}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13c0, 0x6}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1418, 0xc}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1478, 0x12}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1508, 0x90}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x800, 0x2}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x820, 0x10}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x820 + 0x40, 0x21ae5}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2908, 0xa}, +#define TSEM_PORT0_END 213 +#define TSEM_PORT1_START 213 + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x45b8, 0x16c}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x45b8 + 0x5b0, 0x21ae7}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1398, 0xa}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x13d8, 0x6}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1448, 0xc}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x14c0, 0x12}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x1748, 0x90}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x808, 0x2}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x868, 0x10}, + {OP_SW, TSEM_REG_FAST_MEMORY + 0x868 + 0x40, 0x21ae9}, + {OP_ZR, TSEM_REG_FAST_MEMORY + 0x2930, 0xa}, +#define TSEM_PORT1_END 224 +#define MISC_COMMON_START 224 + {OP_WR, MISC_REG_GRC_TIMEOUT_EN, 0x1}, + {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911}, + {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0}, + {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424}, + {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0}, + {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209}, +#define MISC_COMMON_END 230 +#define NIG_COMMON_START 230 + {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1}, + {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1}, + {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1}, + {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1}, + {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1}, +#define NIG_COMMON_END 235 +#define NIG_PORT0_START 235 + {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000}, + {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x26}, + {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0}, + {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4}, + {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1}, + {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0}, + {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30}, + {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1}, + {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1}, + {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1}, + {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1}, +#define NIG_PORT0_END 246 +#define NIG_PORT1_START 246 + {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000}, + {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x26}, + {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0}, + {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4}, + {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1}, + {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0}, + {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30}, + {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1}, + {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1}, + {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1}, + {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1}, +#define NIG_PORT1_END 257 +#define UPB_COMMON_START 257 + {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20}, +#define UPB_COMMON_END 258 +#define CSDM_COMMON_START 258 + {OP_WR, CSDM_REG_CFC_RSP_START_ADDR, 0xa11}, + {OP_WR, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00}, + {OP_WR, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04}, + {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff}, + {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff}, + {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff}, + {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff}, + {OP_ZR, CSDM_REG_AGG_INT_EVENT_0, 0x80}, + {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff}, + {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f}, + {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff}, + {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf}, + {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, + {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, + {OP_WR, CSDM_REG_TIMER_TICK, 0x3e8}, +#define CSDM_COMMON_END 285 +#define USDM_COMMON_START 285 + {OP_WR, USDM_REG_CFC_RSP_START_ADDR, 0xa11}, + {OP_WR, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00}, + {OP_WR, USDM_REG_Q_COUNTER_START_ADDR, 0xa04}, + {OP_WR, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21}, + {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff}, + {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff}, + {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff}, + {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff}, + {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46}, + {OP_ZR, USDM_REG_AGG_INT_EVENT_1, 0x5f}, + {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1}, + {OP_ZR, USDM_REG_AGG_INT_MODE_1, 0x1f}, + {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff}, + {OP_WR, USDM_REG_ENABLE_IN2, 0x3f}, + {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff}, + {OP_WR, USDM_REG_ENABLE_OUT2, 0xf}, + {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0}, + {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0}, + {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, + {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, + {OP_WR, USDM_REG_TIMER_TICK, 0x3e8}, +#define USDM_COMMON_END 317 +#define CCM_COMMON_START 317 + {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32}, + {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020}, + {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020}, + {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000}, + {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33}, + {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0}, + {OP_WR, CCM_REG_XSEM_WEIGHT, 0x4}, + {OP_WR, CCM_REG_USEM_WEIGHT, 0x4}, + {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2}, + {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x2}, + {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1}, + {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2}, + {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2}, + {OP_WR, CCM_REG_INV_DONE_Q, 0x1}, + {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1}, + {OP_WR, CCM_REG_GR_LD0_PR, 0x1}, + {OP_WR, CCM_REG_GR_LD1_PR, 0x2}, + {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1}, + {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20}, + {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40}, + {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40}, + {OP_WR, CCM_REG_XX_INIT_CRD, 0x3}, + {OP_WR, CCM_REG_XX_MSG_NUM, 0x18}, + {OP_ZR, CCM_REG_XX_TABLE, 0x12}, + {OP_SW, CCM_REG_XX_DESCR_TABLE, 0x241aeb}, + {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1}, + {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2}, + {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8}, + {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8}, + {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4}, + {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4}, + {OP_WR, CCM_REG_QOS_PHYS_QNUM0_0, 0x9}, + {OP_WR, CCM_REG_QOS_PHYS_QNUM0_1, 0x29}, + {OP_WR, CCM_REG_QOS_PHYS_QNUM1_0, 0xa}, + {OP_WR, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a}, + {OP_ZR, CCM_REG_QOS_PHYS_QNUM2_0, 0x4}, + {OP_WR, CCM_REG_PHYS_QNUM1_0, 0xc}, + {OP_WR, CCM_REG_PHYS_QNUM1_1, 0x2c}, + {OP_WR, CCM_REG_PHYS_QNUM2_0, 0xb}, + {OP_WR, CCM_REG_PHYS_QNUM2_1, 0x2b}, + {OP_ZR, CCM_REG_PHYS_QNUM3_0, 0x2}, + {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1}, + {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1}, + {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1}, + {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1}, + {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1}, + {OP_WR, CCM_REG_CSDM_IFEN, 0x1}, + {OP_WR, CCM_REG_TSEM_IFEN, 0x1}, + {OP_WR, CCM_REG_XSEM_IFEN, 0x1}, + {OP_WR, CCM_REG_USEM_IFEN, 0x1}, + {OP_WR, CCM_REG_PBF_IFEN, 0x1}, + {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1}, + {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1}, + {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1}, + {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1}, + {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1}, +#define CCM_COMMON_END 373 +#define UCM_COMMON_START 373 + {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32}, + {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020}, + {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020}, + {OP_WR, UCM_REG_TM_UCM_HDR, 0x30}, + {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000}, + {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33}, + {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30}, + {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31}, + {OP_WR, UCM_REG_TSEM_WEIGHT, 0x3}, + {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0}, + {OP_WR, UCM_REG_CP_WEIGHT, 0x0}, + {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x6}, + {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1}, + {OP_WR, UCM_REG_INV_CFLG_Q, 0x1}, + {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1}, + {OP_WR, UCM_REG_GR_LD0_PR, 0x1}, + {OP_WR, UCM_REG_GR_LD1_PR, 0x2}, + {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1}, + {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40}, + {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40}, + {OP_WR, UCM_REG_TM_INIT_CRD, 0x4}, + {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20}, + {OP_WR, UCM_REG_XX_INIT_CRD, 0xc}, + {OP_WR, UCM_REG_XX_MSG_NUM, 0x20}, + {OP_ZR, UCM_REG_XX_TABLE, 0x12}, + {OP_SW, UCM_REG_XX_DESCR_TABLE, 0x201b0f}, + {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0xa}, + {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7}, + {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf}, + {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10}, + {OP_ZR, UCM_REG_N_SM_CTX_LD_4, 0x4}, + {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3}, + {OP_WR, UCM_REG_PHYS_QNUM0_0, 0xf}, + {OP_WR, UCM_REG_PHYS_QNUM0_1, 0x2f}, + {OP_WR, UCM_REG_PHYS_QNUM1_0, 0xe}, + {OP_WR, UCM_REG_PHYS_QNUM1_1, 0x2e}, + {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1}, + {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1}, + {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1}, + {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1}, + {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1}, + {OP_WR, UCM_REG_USDM_IFEN, 0x1}, + {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1}, + {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1}, + {OP_WR, UCM_REG_TSEM_IFEN, 0x1}, + {OP_WR, UCM_REG_CSEM_IFEN, 0x1}, + {OP_WR, UCM_REG_XSEM_IFEN, 0x1}, + {OP_WR, UCM_REG_DORQ_IFEN, 0x1}, + {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1}, + {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1}, + {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1}, + {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1}, + {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1}, +#define UCM_COMMON_END 426 +#define USEM_COMMON_START 426 + {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0}, + {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0}, + {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0}, + {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0}, + {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0}, + {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0}, + {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1}, + {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2}, + {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3}, + {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0}, + {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4}, + {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1}, + {OP_WR, USEM_REG_TS_0_AS, 0x0}, + {OP_WR, USEM_REG_TS_1_AS, 0x1}, + {OP_WR, USEM_REG_TS_2_AS, 0x4}, + {OP_WR, USEM_REG_TS_3_AS, 0x0}, + {OP_WR, USEM_REG_TS_4_AS, 0x1}, + {OP_WR, USEM_REG_TS_5_AS, 0x3}, + {OP_WR, USEM_REG_TS_6_AS, 0x0}, + {OP_WR, USEM_REG_TS_7_AS, 0x1}, + {OP_WR, USEM_REG_TS_8_AS, 0x4}, + {OP_WR, USEM_REG_TS_9_AS, 0x0}, + {OP_WR, USEM_REG_TS_10_AS, 0x1}, + {OP_WR, USEM_REG_TS_11_AS, 0x3}, + {OP_WR, USEM_REG_TS_12_AS, 0x0}, + {OP_WR, USEM_REG_TS_13_AS, 0x1}, + {OP_WR, USEM_REG_TS_14_AS, 0x4}, + {OP_WR, USEM_REG_TS_15_AS, 0x0}, + {OP_WR, USEM_REG_TS_16_AS, 0x4}, + {OP_WR, USEM_REG_TS_17_AS, 0x3}, + {OP_ZR, USEM_REG_TS_18_AS, 0x2}, + {OP_WR, USEM_REG_ENABLE_IN, 0x3fff}, + {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff}, + {OP_WR, USEM_REG_FIC0_DISABLE, 0x0}, + {OP_WR, USEM_REG_FIC1_DISABLE, 0x0}, + {OP_WR, USEM_REG_PAS_DISABLE, 0x0}, + {OP_WR, USEM_REG_THREADS_LIST, 0xffff}, + {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x5000, 0x102}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1020, 0xc8}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1000, 0x2}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1e20, 0x40}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x400}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x2410, 0x6}, + {OP_SW, USEM_REG_FAST_MEMORY + 0x2410 + 0x18, 0x21b2f}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b68, 0x2}, + {OP_SW, USEM_REG_FAST_MEMORY + 0x4b68 + 0x8, 0x21b31}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b10, 0x2}, + {OP_SW, USEM_REG_FAST_MEMORY + 0x2c30, 0x21b33}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, + {OP_SW, USEM_REG_FAST_MEMORY + 0x10c00, 0x101b35}, + {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0}, + {OP_SW, USEM_REG_FAST_MEMORY + 0x10c40, 0x101b45}, + {OP_ZP, USEM_REG_INT_TABLE, 0xb41b55}, + {OP_ZP, USEM_REG_PRAM, 0x32d01b82}, + {OP_ZP, USEM_REG_PRAM + 0x8000, 0x32172836}, + {OP_ZP, USEM_REG_PRAM + 0x10000, 0x1a7a34bc}, + {OP_ZP, USEM_REG_PRAM + 0x18000, 0x5f3b5b}, + {OP_ZP, USEM_REG_PRAM + 0x20000, 0x5f3b73}, + {OP_ZP, USEM_REG_PRAM + 0x28000, 0x5f3b8b}, + {OP_ZP, USEM_REG_PRAM + 0x30000, 0x5f3ba3}, + {OP_ZP, USEM_REG_PRAM + 0x38000, 0x5f3bbb}, +#define USEM_COMMON_END 498 +#define USEM_PORT0_START 498 + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1400, 0xa0}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1900, 0xa}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1950, 0x2e}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d00, 0x24}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3000, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3100, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3200, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3300, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3400, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3500, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3600, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3700, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3800, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3900, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f00, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x2400, 0x2}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4b78, 0x52}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e08, 0xc}, +#define USEM_PORT0_END 521 +#define USEM_PORT1_START 521 + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1680, 0xa0}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1928, 0xa}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1a08, 0x2e}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x1d90, 0x24}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3080, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3180, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3280, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3380, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3480, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3580, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3680, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3780, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3880, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3980, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3a80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3b80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3c80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3d80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3e80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x3f80, 0x20}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x2408, 0x2}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4cc0, 0x52}, + {OP_ZR, USEM_REG_FAST_MEMORY + 0x4e38, 0xc}, +#define USEM_PORT1_END 544 +#define CSEM_COMMON_START 544 + {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0}, + {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0}, + {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0}, + {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0}, + {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0}, + {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0}, + {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1}, + {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2}, + {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3}, + {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0}, + {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4}, + {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1}, + {OP_WR, CSEM_REG_TS_0_AS, 0x0}, + {OP_WR, CSEM_REG_TS_1_AS, 0x1}, + {OP_WR, CSEM_REG_TS_2_AS, 0x4}, + {OP_WR, CSEM_REG_TS_3_AS, 0x0}, + {OP_WR, CSEM_REG_TS_4_AS, 0x1}, + {OP_WR, CSEM_REG_TS_5_AS, 0x3}, + {OP_WR, CSEM_REG_TS_6_AS, 0x0}, + {OP_WR, CSEM_REG_TS_7_AS, 0x1}, + {OP_WR, CSEM_REG_TS_8_AS, 0x4}, + {OP_WR, CSEM_REG_TS_9_AS, 0x0}, + {OP_WR, CSEM_REG_TS_10_AS, 0x1}, + {OP_WR, CSEM_REG_TS_11_AS, 0x3}, + {OP_WR, CSEM_REG_TS_12_AS, 0x0}, + {OP_WR, CSEM_REG_TS_13_AS, 0x1}, + {OP_WR, CSEM_REG_TS_14_AS, 0x4}, + {OP_WR, CSEM_REG_TS_15_AS, 0x0}, + {OP_WR, CSEM_REG_TS_16_AS, 0x4}, + {OP_WR, CSEM_REG_TS_17_AS, 0x3}, + {OP_ZR, CSEM_REG_TS_18_AS, 0x2}, + {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff}, + {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff}, + {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0}, + {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0}, + {OP_WR, CSEM_REG_PAS_DISABLE, 0x0}, + {OP_WR, CSEM_REG_THREADS_LIST, 0xffff}, + {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x5000, 0x42}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1000, 0x2}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3070, 0x80}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x4280, 0x4}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240}, + {OP_SW, CSEM_REG_FAST_MEMORY + 0x25c0 + 0x900, 0x83bd3}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff}, + {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c00, 0x103bdb}, + {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0}, + {OP_SW, CSEM_REG_FAST_MEMORY + 0x10c40, 0x103beb}, + {OP_ZP, CSEM_REG_INT_TABLE, 0x5f3bfb}, + {OP_ZP, CSEM_REG_PRAM, 0x32423c13}, + {OP_ZP, CSEM_REG_PRAM + 0x8000, 0xf2148a4}, + {OP_ZP, CSEM_REG_PRAM + 0x10000, 0x5f4c6d}, + {OP_ZP, CSEM_REG_PRAM + 0x18000, 0x5f4c85}, + {OP_ZP, CSEM_REG_PRAM + 0x20000, 0x5f4c9d}, + {OP_ZP, CSEM_REG_PRAM + 0x28000, 0x5f4cb5}, + {OP_ZP, CSEM_REG_PRAM + 0x30000, 0x5f4ccd}, + {OP_ZP, CSEM_REG_PRAM + 0x38000, 0x5f4ce5}, +#define CSEM_COMMON_END 609 +#define CSEM_PORT0_START 609 + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1900, 0x10}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1980, 0x30}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2300, 0x2}, + {OP_SW, CSEM_REG_FAST_MEMORY + 0x2300 + 0x8, 0x24cfd}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3040, 0x6}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2410, 0x30}, +#define CSEM_PORT0_END 616 +#define CSEM_PORT1_START 616 + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1940, 0x10}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x2310, 0x2}, + {OP_SW, CSEM_REG_FAST_MEMORY + 0x2310 + 0x8, 0x24cff}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x3058, 0x6}, + {OP_ZR, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30}, +#define CSEM_PORT1_END 623 +#define XPB_COMMON_START 623 + {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20}, +#define XPB_COMMON_END 624 +#define DQ_COMMON_START 624 + {OP_WR, DORQ_REG_MODE_ACT, 0x2}, + {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3}, + {OP_WR, DORQ_REG_OUTST_REQ, 0x4}, + {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8}, + {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2}, + {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90}, + {OP_WR, DORQ_REG_CMHEAD_RX, 0x90}, + {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090}, + {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000}, + {OP_WR, DORQ_REG_AGG_CMD0, 0x8a}, + {OP_WR, DORQ_REG_AGG_CMD1, 0x80}, + {OP_WR, DORQ_REG_AGG_CMD2, 0x90}, + {OP_WR, DORQ_REG_AGG_CMD3, 0x80}, + {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6}, + {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0}, + {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c}, + {OP_WR, DORQ_REG_REGN, 0x7c1004}, + {OP_WR, DORQ_REG_IF_EN, 0xf}, +#define DQ_COMMON_END 642 +#define TIMERS_COMMON_START 642 + {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2}, + {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c}, + {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1}, + {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1}, + {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1}, + {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1}, + {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1}, + {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1}, + {OP_WR, TM_REG_PCIARB_CRDCNT_VAL, 0x2}, + {OP_WR, TM_REG_TIMER_TICK_SIZE, 0x3d090}, + {OP_WR, TM_REG_CL0_CONT_REGION, 0x8}, + {OP_WR, TM_REG_CL1_CONT_REGION, 0xc}, + {OP_WR, TM_REG_CL2_CONT_REGION, 0x10}, + {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20}, + {OP_WR, TM_REG_EN_TIMERS, 0x1}, + {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1}, + {OP_WR, TM_REG_EN_CL0_INPUT, 0x1}, + {OP_WR, TM_REG_EN_CL1_INPUT, 0x1}, + {OP_WR, TM_REG_EN_CL2_INPUT, 0x1}, +#define TIMERS_COMMON_END 661 +#define TIMERS_PORT0_START 661 + {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2}, +#define TIMERS_PORT0_END 662 +#define TIMERS_PORT1_START 662 + {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2}, +#define TIMERS_PORT1_END 663 +#define XSDM_COMMON_START 663 + {OP_WR, XSDM_REG_CFC_RSP_START_ADDR, 0xa14}, + {OP_WR, XSDM_REG_CMP_COUNTER_START_ADDR, 0xa00}, + {OP_WR, XSDM_REG_Q_COUNTER_START_ADDR, 0xa04}, + {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff}, + {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff}, + {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff}, + {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff}, + {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20}, + {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20}, + {OP_ZR, XSDM_REG_AGG_INT_EVENT_2, 0x5e}, + {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1}, + {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f}, + {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff}, + {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f}, + {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff}, + {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf}, + {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0}, + {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0}, + {OP_WR, XSDM_REG_TIMER_TICK, 0x3e8}, +#define XSDM_COMMON_END 694 +#define QM_COMMON_START 694 + {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6}, + {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5}, + {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa}, + {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5}, + {OP_WR, QM_REG_PCIREQAT, 0x2}, + {OP_WR, QM_REG_CMINITCRD_0, 0x4}, + {OP_WR, QM_REG_CMINITCRD_1, 0x4}, + {OP_WR, QM_REG_CMINITCRD_2, 0x4}, + {OP_WR, QM_REG_CMINITCRD_3, 0x4}, + {OP_WR, QM_REG_CMINITCRD_4, 0x4}, + {OP_WR, QM_REG_CMINITCRD_5, 0x4}, + {OP_WR, QM_REG_CMINITCRD_6, 0x4}, + {OP_WR, QM_REG_CMINITCRD_7, 0x4}, + {OP_WR, QM_REG_OUTLDREQ, 0x4}, + {OP_WR, QM_REG_CTXREG_0, 0x7c}, + {OP_WR, QM_REG_CTXREG_1, 0x3d}, + {OP_WR, QM_REG_CTXREG_2, 0x3f}, + {OP_WR, QM_REG_CTXREG_3, 0x9c}, + {OP_WR, QM_REG_ENSEC, 0x7}, + {OP_ZR, QM_REG_QVOQIDX_0, 0x5}, + {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_5, 0x0}, + {OP_WR, QM_REG_QVOQIDX_6, 0x4}, + {OP_WR, QM_REG_QVOQIDX_7, 0x4}, + {OP_WR, QM_REG_QVOQIDX_8, 0x2}, + {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004}, + {OP_WR, QM_REG_QVOQIDX_9, 0x5}, + {OP_WR, QM_REG_QVOQIDX_10, 0x5}, + {OP_WR, QM_REG_QVOQIDX_11, 0x5}, + {OP_WR, QM_REG_QVOQIDX_12, 0x5}, + {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001}, + {OP_WR, QM_REG_QVOQIDX_13, 0x8}, + {OP_WR, QM_REG_QVOQIDX_14, 0x6}, + {OP_WR, QM_REG_QVOQIDX_15, 0x7}, + {OP_WR, QM_REG_QVOQIDX_16, 0x0}, + {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120}, + {OP_ZR, QM_REG_QVOQIDX_17, 0x4}, + {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101}, + {OP_ZR, QM_REG_QVOQIDX_21, 0x4}, + {OP_WR, QM_REG_WRRWEIGHTS_5, 0x1010101}, + {OP_ZR, QM_REG_QVOQIDX_25, 0x4}, + {OP_WR, QM_REG_WRRWEIGHTS_6, 0x1010101}, + {OP_ZR, QM_REG_QVOQIDX_29, 0x3}, + {OP_WR, QM_REG_QVOQIDX_32, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_7, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_33, 0x1}, + {OP_WR, QM_REG_QVOQIDX_34, 0x1}, + {OP_WR, QM_REG_QVOQIDX_35, 0x1}, + {OP_WR, QM_REG_QVOQIDX_36, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_37, 0x1}, + {OP_WR, QM_REG_QVOQIDX_38, 0x4}, + {OP_WR, QM_REG_QVOQIDX_39, 0x4}, + {OP_WR, QM_REG_QVOQIDX_40, 0x2}, + {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004}, + {OP_WR, QM_REG_QVOQIDX_41, 0x5}, + {OP_WR, QM_REG_QVOQIDX_42, 0x5}, + {OP_WR, QM_REG_QVOQIDX_43, 0x5}, + {OP_WR, QM_REG_QVOQIDX_44, 0x5}, + {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001}, + {OP_WR, QM_REG_QVOQIDX_45, 0x8}, + {OP_WR, QM_REG_QVOQIDX_46, 0x6}, + {OP_WR, QM_REG_QVOQIDX_47, 0x7}, + {OP_WR, QM_REG_QVOQIDX_48, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120}, + {OP_WR, QM_REG_QVOQIDX_49, 0x1}, + {OP_WR, QM_REG_QVOQIDX_50, 0x1}, + {OP_WR, QM_REG_QVOQIDX_51, 0x1}, + {OP_WR, QM_REG_QVOQIDX_52, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_53, 0x1}, + {OP_WR, QM_REG_QVOQIDX_54, 0x1}, + {OP_WR, QM_REG_QVOQIDX_55, 0x1}, + {OP_WR, QM_REG_QVOQIDX_56, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_13, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_57, 0x1}, + {OP_WR, QM_REG_QVOQIDX_58, 0x1}, + {OP_WR, QM_REG_QVOQIDX_59, 0x1}, + {OP_WR, QM_REG_QVOQIDX_60, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_14, 0x1010101}, + {OP_WR, QM_REG_QVOQIDX_61, 0x1}, + {OP_WR, QM_REG_QVOQIDX_62, 0x1}, + {OP_WR, QM_REG_QVOQIDX_63, 0x1}, + {OP_WR, QM_REG_WRRWEIGHTS_15, 0x1010101}, + {OP_WR, QM_REG_VOQQMASK_0_LSB, 0xffff003f}, + {OP_ZR, QM_REG_VOQQMASK_0_MSB, 0x2}, + {OP_WR, QM_REG_VOQQMASK_1_MSB, 0xffff003f}, + {OP_WR, QM_REG_VOQQMASK_2_LSB, 0x100}, + {OP_WR, QM_REG_VOQQMASK_2_MSB, 0x100}, + {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2}, + {OP_WR, QM_REG_VOQQMASK_4_LSB, 0xc0}, + {OP_WR, QM_REG_VOQQMASK_4_MSB, 0xc0}, + {OP_WR, QM_REG_VOQQMASK_5_LSB, 0x1e00}, + {OP_WR, QM_REG_VOQQMASK_5_MSB, 0x1e00}, + {OP_WR, QM_REG_VOQQMASK_6_LSB, 0x4000}, + {OP_WR, QM_REG_VOQQMASK_6_MSB, 0x4000}, + {OP_WR, QM_REG_VOQQMASK_7_LSB, 0x8000}, + {OP_WR, QM_REG_VOQQMASK_7_MSB, 0x8000}, + {OP_WR, QM_REG_VOQQMASK_8_LSB, 0x2000}, + {OP_WR, QM_REG_VOQQMASK_8_MSB, 0x2000}, + {OP_ZR, QM_REG_VOQQMASK_9_LSB, 0x7}, + {OP_WR, QM_REG_VOQPORT_1, 0x1}, + {OP_ZR, QM_REG_VOQPORT_2, 0xa}, + {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08}, + {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40}, + {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100}, + {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20}, + {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17}, + {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80}, + {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200}, + {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0}, + {OP_WR, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff}, + {OP_WR, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff}, + {OP_WR, QM_REG_ENBYPVOQMASK, 0x13}, + {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f}, + {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140}, + {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140}, + {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2}, + {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0}, + {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7}, + {OP_WR, QM_REG_TASKCRDCOST_0, 0x48}, + {OP_WR, QM_REG_TASKCRDCOST_1, 0x48}, + {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2}, + {OP_WR, QM_REG_TASKCRDCOST_4, 0x48}, + {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7}, + {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000}, + {OP_WR, QM_REG_BYTECRDCOST, 0x25e4}, + {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff}, + {OP_WR, QM_REG_ENBYTECRD_LSB, 0x7}, + {OP_WR, QM_REG_ENBYTECRD_MSB, 0x7}, + {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0}, + {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff}, + {OP_WR, QM_REG_FUNCNUMSEL_LSB, 0x0}, + {OP_WR, QM_REG_FUNCNUMSEL_MSB, 0xffffffff}, + {OP_WR, QM_REG_CMINTEN, 0xff}, +#define QM_COMMON_END 829 +#define PBF_COMMON_START 829 + {OP_WR, PBF_REG_INIT, 0x1}, + {OP_WR, PBF_REG_INIT_P4, 0x1}, + {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1}, + {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff}, + {OP_WR, PBF_REG_INIT_P4, 0x0}, + {OP_WR, PBF_REG_INIT, 0x0}, + {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0}, +#define PBF_COMMON_END 836 +#define PBF_PORT0_START 836 + {OP_WR, PBF_REG_INIT_P0, 0x1}, + {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1}, + {OP_WR, PBF_REG_INIT_P0, 0x0}, + {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0}, +#define PBF_PORT0_END 840 +#define PBF_PORT1_START 840 + {OP_WR, PBF_REG_INIT_P1, 0x1}, + {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1}, + {OP_WR, PBF_REG_INIT_P1, 0x0}, + {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0}, +#define PBF_PORT1_END 844 +#define XCM_COMMON_START 844 + {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32}, + {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020}, + {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020}, + {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030}, + {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000}, + {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33}, + {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30}, + {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31}, + {OP_WR, XCM_REG_STORM_WEIGHT, 0x2}, + {OP_WR, XCM_REG_TSEM_WEIGHT, 0x5}, + {OP_WR, XCM_REG_CSEM_WEIGHT, 0x2}, + {OP_WR, XCM_REG_USEM_WEIGHT, 0x2}, + {OP_WR, XCM_REG_PBF_WEIGHT, 0x7}, + {OP_WR, XCM_REG_NIG1_WEIGHT, 0x1}, + {OP_WR, XCM_REG_CP_WEIGHT, 0x0}, + {OP_WR, XCM_REG_XSDM_WEIGHT, 0x5}, + {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x3}, + {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1}, + {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6}, + {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0}, + {OP_WR, XCM_REG_AUX1_Q, 0x2}, + {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1}, + {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1}, + {OP_WR, XCM_REG_GR_LD0_PR, 0x1}, + {OP_WR, XCM_REG_GR_LD1_PR, 0x2}, + {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1}, + {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40}, + {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40}, + {OP_WR, XCM_REG_TM_INIT_CRD, 0x4}, + {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20}, + {OP_WR, XCM_REG_XX_INIT_CRD, 0x2}, + {OP_WR, XCM_REG_XX_MSG_NUM, 0x1f}, + {OP_ZR, XCM_REG_XX_TABLE, 0x12}, + {OP_SW, XCM_REG_XX_DESCR_TABLE, 0x1f4d01}, + {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf}, + {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7}, + {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb}, + {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe}, + {OP_ZR, XCM_REG_N_SM_CTX_LD_4, 0x4}, + {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4}, + {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1}, + {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1}, + {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1}, + {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1}, + {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1}, + {OP_WR, XCM_REG_XSDM_IFEN, 0x1}, + {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1}, + {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1}, + {OP_WR, XCM_REG_TSEM_IFEN, 0x1}, + {OP_WR, XCM_REG_CSEM_IFEN, 0x1}, + {OP_WR, XCM_REG_USEM_IFEN, 0x1}, + {OP_WR, XCM_REG_DORQ_IFEN, 0x1}, + {OP_WR, XCM_REG_PBF_IFEN, 0x1}, + {OP_WR, XCM_REG_NIG0_IFEN, 0x1}, + {OP_WR, XCM_REG_NIG1_IFEN, 0x1}, + {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1}, + {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1}, + {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1}, + {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1}, + {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1}, +#define XCM_COMMON_END 904 +#define XCM_PORT0_START 904 + {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8}, + {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2}, + {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0}, + {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0}, + {OP_WR, XCM_REG_WU_DA_CNT_CMD00, 0x2}, + {OP_WR, XCM_REG_WU_DA_CNT_CMD10, 0x2}, + {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff}, + {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff}, +#define XCM_PORT0_END 912 +#define XCM_PORT1_START 912 + {OP_WR, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8}, + {OP_WR, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2}, + {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0}, + {OP_WR, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0}, + {OP_WR, XCM_REG_WU_DA_CNT_CMD01, 0x2}, + {OP_WR, XCM_REG_WU_DA_CNT_CMD11, 0x2}, + {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff}, + {OP_WR, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff}, +#define XCM_PORT1_END 920 +#define XSEM_COMMON_START 920 + {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0}, + {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0}, + {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0}, + {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0}, + {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0}, + {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0}, + {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1}, + {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2}, + {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3}, + {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0}, + {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4}, + {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1}, + {OP_WR, XSEM_REG_TS_0_AS, 0x0}, + {OP_WR, XSEM_REG_TS_1_AS, 0x1}, + {OP_WR, XSEM_REG_TS_2_AS, 0x4}, + {OP_WR, XSEM_REG_TS_3_AS, 0x0}, + {OP_WR, XSEM_REG_TS_4_AS, 0x1}, + {OP_WR, XSEM_REG_TS_5_AS, 0x3}, + {OP_WR, XSEM_REG_TS_6_AS, 0x0}, + {OP_WR, XSEM_REG_TS_7_AS, 0x1}, + {OP_WR, XSEM_REG_TS_8_AS, 0x4}, + {OP_WR, XSEM_REG_TS_9_AS, 0x0}, + {OP_WR, XSEM_REG_TS_10_AS, 0x1}, + {OP_WR, XSEM_REG_TS_11_AS, 0x3}, + {OP_WR, XSEM_REG_TS_12_AS, 0x0}, + {OP_WR, XSEM_REG_TS_13_AS, 0x1}, + {OP_WR, XSEM_REG_TS_14_AS, 0x4}, + {OP_WR, XSEM_REG_TS_15_AS, 0x0}, + {OP_WR, XSEM_REG_TS_16_AS, 0x4}, + {OP_WR, XSEM_REG_TS_17_AS, 0x3}, + {OP_ZR, XSEM_REG_TS_18_AS, 0x2}, + {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff}, + {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff}, + {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0}, + {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0}, + {OP_WR, XSEM_REG_PAS_DISABLE, 0x0}, + {OP_WR, XSEM_REG_THREADS_LIST, 0xffff}, + {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x55d8, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x48}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1000, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5128, 0x92}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x5378, 0x0}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x5380, 0x24d20}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x5428, 0x44d22}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1518, 0x1}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1830, 0x0}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1838, 0x0}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x1820, 0x24d26}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad8, 0x24d28}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b08, 0x4}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x1f50, 0x24d2a}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c00, 0x104d2c}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c40, 0x84d3c}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c60, 0x84d44}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x3000000}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x10c80, 0x84d4c}, + {OP_ZP, XSEM_REG_INT_TABLE, 0x814d54}, + {OP_ZP, XSEM_REG_PRAM, 0x35774d75}, + {OP_ZP, XSEM_REG_PRAM + 0x8000, 0x36525ad3}, + {OP_ZP, XSEM_REG_PRAM + 0x10000, 0x27266868}, + {OP_ZP, XSEM_REG_PRAM + 0x18000, 0x5e7232}, + {OP_ZP, XSEM_REG_PRAM + 0x20000, 0x5e724a}, + {OP_ZP, XSEM_REG_PRAM + 0x28000, 0x5e7262}, + {OP_ZP, XSEM_REG_PRAM + 0x30000, 0x5e727a}, + {OP_ZP, XSEM_REG_PRAM + 0x38000, 0x5e7292}, +#define XSEM_COMMON_END 1000 +#define XSEM_PORT0_START 1000 + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1400, 0xa}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1450, 0x6}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5388, 0xc}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x5388 + 0x30, 0x272aa}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x55e0, 0x772ac}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5600, 0x7}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1500, 0x0}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1508, 0x1}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3020, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3030, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3000, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3010, 0x2}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x3040, 0x0}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3048, 0xc}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x3048 + 0x30, 0x272b3}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x30b8, 0x1}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x272b5}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4b18, 0x42}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d28, 0x4}, +#define XSEM_PORT0_END 1019 +#define XSEM_PORT1_START 1019 + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1428, 0xa}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x1468, 0x6}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x53c0, 0xc}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x53c0 + 0x30, 0x272b7}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x5620, 0x772b9}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5640, 0x7}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x1504, 0x0}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x150c, 0x1}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3028, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3038, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3008, 0x2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3018, 0x2}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x3044, 0x0}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x3080, 0xc}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x3080 + 0x30, 0x272c0}, + {OP_WR, XSEM_REG_FAST_MEMORY + 0x30bc, 0x1}, + {OP_SW, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x272c2}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4c20, 0x42}, + {OP_ZR, XSEM_REG_FAST_MEMORY + 0x4d38, 0x4}, +#define XSEM_PORT1_END 1038 +#define CDU_COMMON_START 1038 + {OP_WR, CDU_REG_CDU_CONTROL0, 0x1}, + {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000}, + {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d}, + {OP_WB, CDU_REG_L1TT, 0x20072c4}, + {OP_WB, CDU_REG_MATT, 0x2074c4}, + {OP_ZR, CDU_REG_MATT + 0x80, 0x20}, +#define CDU_COMMON_END 1044 +#define DMAE_COMMON_START 1044 + {OP_WR, DMAE_REG_CRC16C_INIT, 0x0}, + {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1}, + {OP_WR, DMAE_REG_PXP_REQ_INIT_CRD, 0x2}, + {OP_WR, DMAE_REG_PCI_IFEN, 0x1}, + {OP_WR, DMAE_REG_GRC_IFEN, 0x1}, +#define DMAE_COMMON_END 1049 +#define PXP_COMMON_START 1049 + {OP_SI, PXP_REG_HST_INBOUND_INT + 0x400, 0x574e4}, + {OP_SI, PXP_REG_HST_INBOUND_INT + 0x420, 0x574e9}, + {OP_SI, PXP_REG_HST_INBOUND_INT, 0x574ee}, +#define PXP_COMMON_END 1052 +#define CFC_COMMON_START 1052 + {OP_WR, CFC_REG_CONTROL0, 0x10}, + {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff}, + {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a}, +#define CFC_COMMON_END 1055 +#define HC_COMMON_START 1055 + {OP_ZR, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4}, +#define HC_COMMON_END 1056 +#define HC_PORT0_START 1056 + {OP_WR, HC_REG_CONFIG_0, 0x1080}, + {OP_ZR, HC_REG_UC_RAM_ADDR_0, 0x2}, + {OP_WR, HC_REG_ATTN_NUM_P0, 0x10}, + {OP_WR, HC_REG_LEADING_EDGE_0, 0xffff}, + {OP_WR, HC_REG_TRAILING_EDGE_0, 0xffff}, + {OP_WR, HC_REG_AGG_INT_0, 0x0}, + {OP_WR, HC_REG_ATTN_IDX, 0x0}, + {OP_ZR, HC_REG_ATTN_BIT, 0x2}, + {OP_WR, HC_REG_VQID_0, 0x2b5}, + {OP_WR, HC_REG_PCI_CONFIG_0, 0x0}, + {OP_ZR, HC_REG_P0_PROD_CONS, 0x4a}, + {OP_ZR, HC_REG_PBA_COMMAND, 0x2}, + {OP_WR, HC_REG_INT_MASK, 0x1ffff}, + {OP_WR, HC_REG_CONFIG_0, 0x1a82}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS, 0x24}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a}, +#define HC_PORT0_END 1074 +#define HC_PORT1_START 1074 + {OP_WR, HC_REG_CONFIG_1, 0x1080}, + {OP_ZR, HC_REG_UC_RAM_ADDR_1, 0x2}, + {OP_WR, HC_REG_ATTN_NUM_P1, 0x10}, + {OP_WR, HC_REG_LEADING_EDGE_1, 0xffff}, + {OP_WR, HC_REG_TRAILING_EDGE_1, 0xffff}, + {OP_WR, HC_REG_AGG_INT_1, 0x0}, + {OP_WR, HC_REG_ATTN_IDX + 0x4, 0x0}, + {OP_ZR, HC_REG_ATTN_BIT + 0x8, 0x2}, + {OP_WR, HC_REG_VQID_1, 0x2b5}, + {OP_WR, HC_REG_PCI_CONFIG_1, 0x0}, + {OP_ZR, HC_REG_P1_PROD_CONS, 0x4a}, + {OP_ZR, HC_REG_PBA_COMMAND + 0x8, 0x2}, + {OP_WR, HC_REG_INT_MASK + 0x4, 0x1ffff}, + {OP_WR, HC_REG_CONFIG_1, 0x1a82}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a}, + {OP_ZR, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a}, +#define HC_PORT1_END 1092 +#define PXP2_COMMON_START 1092 + {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38324}, + {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_1, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_0, 0xffff5330}, + {OP_WR, PXP2_REG_PGL_INT_XSDM_1, 0xffff5348}, + {OP_WR, PXP2_REG_PGL_INT_USDM_0, 0xf0003000}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4}, + {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0}, + {OP_WR, PXP2_REG_RD_START_INIT, 0x1}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3}, + {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3}, + {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403}, + {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f}, + {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6}, + {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6}, + {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306}, + {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13}, + {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6}, + {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004}, + {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004}, + {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440}, + {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440}, + {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1}, +#define PXP2_COMMON_END 1200 +#define MISC_AEU_COMMON_START 1200 + {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16}, +#define MISC_AEU_COMMON_END 1201 +#define MISC_AEU_PORT0_START 1201 + {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000}, + {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef}, + {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff}, + {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0}, + {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0}, + {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000}, + {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5}, + {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000}, + {OP_ZR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14}, + {OP_WR, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000}, + {OP_WR, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555}, + {OP_WR, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555}, + {OP_WR, MISC_REG_AEU_ENABLE4_NIG_0, 0x0}, + {OP_WR, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000}, + {OP_WR, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555}, + {OP_WR, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555}, + {OP_WR, MISC_REG_AEU_ENABLE4_PXP_0, 0x0}, + {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0}, + {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3}, + {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7}, +#define MISC_AEU_PORT0_END 1221 +#define MISC_AEU_PORT1_START 1221 + {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000}, + {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef}, + {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff}, + {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0}, + {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0}, + {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000}, + {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5}, + {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000}, + {OP_ZR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14}, + {OP_WR, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000}, + {OP_WR, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555}, + {OP_WR, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555}, + {OP_WR, MISC_REG_AEU_ENABLE4_NIG_1, 0x0}, + {OP_WR, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000}, + {OP_WR, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555}, + {OP_WR, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555}, + {OP_WR, MISC_REG_AEU_ENABLE4_PXP_1, 0x0}, + {OP_WR, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0}, + {OP_ZR, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3}, + {OP_WR, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7} +#define MISC_AEU_PORT1_END 1241 +}; + +static const u32 init_data[] = { + 0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0, + 0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440, + 0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0, + 0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40, + 0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0, + 0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000, + 0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000, + 0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000, + 0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000, + 0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000, + 0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000, + 0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000, + 0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000, + 0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000, + 0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000, + 0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000, + 0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000, + 0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000, + 0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000, + 0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000, + 0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000, + 0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000, + 0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000, + 0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000, + 0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000, + 0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000, + 0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000, + 0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000, + 0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000, + 0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000, + 0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000, + 0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000, + 0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000, + 0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000, + 0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000, + 0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000, + 0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000, + 0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000, + 0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000, + 0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000, + 0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000, + 0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000, + 0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000, + 0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000, + 0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000, + 0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000, + 0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000, + 0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000, + 0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000, + 0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000, + 0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000, + 0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000, + 0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000, + 0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000, + 0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000, + 0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000, + 0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000, + 0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000, + 0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000, + 0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000, + 0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000, + 0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000, + 0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000, + 0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000, + 0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000, + 0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000, + 0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000, + 0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000, + 0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000, + 0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000, + 0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000, + 0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000, + 0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000, + 0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000, + 0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000, + 0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000, + 0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000, + 0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000, + 0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000, + 0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000, + 0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000, + 0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000, + 0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000, + 0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000, + 0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000, + 0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000, + 0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000, + 0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000, + 0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000, + 0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000, + 0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff, + 0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00088b1f, 0x00000000, + 0x51fbff00, 0x03f0c0cf, 0x3130ef8a, 0x22b1c430, 0x3b0143f8, 0x02ecdd01, + 0xdc406ec4, 0x19b7c404, 0x23dfd348, 0xf1476080, 0x03343031, 0x032f3731, + 0x423f2483, 0x4d5011fc, 0x02ef9025, 0xa40cdb15, 0x77280475, 0xf2c060fb, + 0x77629812, 0x056c1144, 0x58c8f22c, 0x4dde4d11, 0x44af950c, 0xe340ff40, + 0xfca8b235, 0x6d081948, 0x8b5f150b, 0x95051f26, 0xd0849577, 0xe76964eb, + 0x00607a36, 0x2726b9d6, 0x00000400, 0x00088b1f, 0x00000000, 0x7dedff00, + 0xd554780b, 0x333ef0b5, 0x64ccce67, 0x093c991e, 0x20f264af, 0xf09c0682, + 0x93a8a808, 0x07be3040, 0x0e22a5e4, 0x27902018, 0xf5e8bd48, 0x620c19bf, + 0x2f06d6b4, 0x93a45a2a, 0xb6968a80, 0x6c1a06c1, 0x822203b4, 0x6b06f5bf, + 0x368b6d7b, 0x2062a28a, 0xa5ebd8b9, 0xaffadaf7, 0x99def6b5, 0x91332673, + 0xfebffdaa, 0x5fa7f7df, 0xf7b3ecdd, 0xf5ed7bd9, 0xb3ef6b5e, 0xa66e6547, + 0x97d8ce5d, 0x9be507f8, 0x232c630a, 0xa1bbd65a, 0xed58cc9c, 0x9ef8731e, + 0xec66c65c, 0x4f2e44b1, 0x12ab7a87, 0xf4dd42b6, 0x4fda9d92, 0x7af5e56f, + 0x9743f773, 0xb9fb3b40, 0x05053d99, 0x589bb1eb, 0x6c276309, 0xf2f5ff8c, + 0xaf3b72fa, 0x5feeb6d6, 0x557fa0cc, 0xe1d995a7, 0x661d13fd, 0x3cd7d63f, + 0xc01984a5, 0x3eefbb50, 0xbf8c046d, 0xdbb4ac22, 0x0a7f50bd, 0xcafb421e, + 0xfb18730e, 0x33bbb9f7, 0x4ec64e03, 0x5798da36, 0x937ef843, 0xd8c453d9, + 0x59eef0aa, 0xaadfa023, 0x04cf8a5d, 0xaadaacf3, 0x8c9f2e44, 0x19b095cf, + 0xe9dea886, 0x1cb1de60, 0xcd192f86, 0xf358eb4b, 0xe30bcc24, 0x0b45b532, + 0x4dbe70b8, 0xc515d79a, 0x0f46c9cf, 0xb5eb23cd, 0xf03cc2cf, 0x144fdd5e, + 0xceb12e1f, 0x30ed82c4, 0xf67de9ff, 0xb89ddb85, 0xa15af5be, 0x258ebf4b, + 0xab1d717b, 0x2cdaadc2, 0xaad5c227, 0x8e8a2f2d, 0xcd33bd57, 0xfc96d708, + 0x7b5d4161, 0x91b2796c, 0xb4616f31, 0x7f318abe, 0x0fe113bb, 0x47c7b36b, + 0x29641f9f, 0x9deacf44, 0x45b5e666, 0x442c67c7, 0x17cccdcf, 0x2eb2bc41, + 0xb74f4f97, 0xdd231e33, 0x7788a4d6, 0x7df3c013, 0x024d8741, 0xf843df4f, + 0x7bf64ca0, 0xfeb0abd6, 0xa3cc99e4, 0x26fef10c, 0x1ed85b0b, 0x900bbd67, + 0x1630a619, 0xb7822664, 0xc26f058e, 0x50d4cfb2, 0x5fc3c005, 0xeb002b24, + 0xefe14fbd, 0xd4bccf5f, 0x9ad1beff, 0xe9bae91f, 0xe6ed92ca, 0x7496b15c, + 0xfa7f2fac, 0xb5321801, 0xbf10cfc2, 0x88ade22a, 0x43321e16, 0xca576bbb, + 0x7abc07c4, 0xc72d95fc, 0x4d93dcf9, 0xa678fa06, 0xa9ea1927, 0xf0635333, + 0xb89cf4eb, 0x4e01d440, 0x827fa9ab, 0x6958cf9a, 0xedf88db6, 0xe48d6c8e, + 0x38cb8ee6, 0x3b64775c, 0x7fa821c3, 0x08b85f17, 0x42f05aea, 0xc07c1c4f, + 0x859626cc, 0xa6c4d065, 0x466f6e0d, 0x941f023c, 0xf8517ce5, 0xa6f5941e, + 0x2814c2fe, 0x21a52b57, 0xc446cbc4, 0x330e9423, 0x3b75c06b, 0xd4f08cac, + 0x7b64a63c, 0xfba78748, 0xb94f0173, 0xb7ef71d1, 0x1f316434, 0xca840f63, + 0xc070ea43, 0xf7102e6f, 0x3cb78462, 0xf7802a12, 0x42c8ef73, 0x9034da7c, + 0x1afcfd03, 0xf3445fcc, 0x1f1e20b7, 0x9d8c7415, 0xcd3856df, 0xaf3dbf30, + 0x5dbf30ca, 0x2781f983, 0x2b5d089f, 0x8e3c07e6, 0xec07ec60, 0x96df9a5a, + 0x6fe68eb7, 0x619558d6, 0xf981a4fe, 0xd3ef38c3, 0x2e6fe609, 0xfeb8d8bc, + 0xf5c655bc, 0xcffd7c6b, 0xf989e685, 0x3ffd6893, 0xfaf8f362, 0xebe2eef3, + 0xfab8c2b7, 0xf803ddf9, 0xefbc476f, 0xdb7f804d, 0xeb8dd379, 0xae31afcf, + 0x7fe7cadf, 0x988b7421, 0xfff349df, 0xd7c2dd82, 0xcd377f9f, 0xf836b56f, + 0xcd64d03c, 0x23086a49, 0x7fe17b5f, 0x802ca0c3, 0x5942a679, 0xbc18ca94, + 0x47961dff, 0x2923b878, 0xfff61e78, 0xcdf8093c, 0x2c0bd519, 0xb94151bc, + 0x5d3c13af, 0xf6896bb9, 0xb2a5783d, 0x064beb93, 0xc00c74fa, 0xb3f3ba77, + 0xf000ffcf, 0xf628ee56, 0x8f24bd99, 0x265bdf0c, 0xe66f5296, 0x902c60f8, + 0xfa85db3d, 0x673d9029, 0x59f9353c, 0x4645e826, 0xe3e20e30, 0x13962d65, + 0x5af93a3d, 0x5f58c5b1, 0x25d63619, 0x24c8a5dc, 0xd8ca8650, 0xf79806d8, + 0x0623e804, 0xd07df27a, 0x647e5847, 0xdda2b761, 0x15f400f8, 0xb572f4d3, + 0x4272e89e, 0xb13ff8e5, 0xf8f241c5, 0x1ad5a6f9, 0x1c7847cb, 0x7cdd6480, + 0x1156f621, 0x58be73ac, 0x04b9e127, 0xcf5f15f5, 0x6bdaaefc, 0xdc02c4c0, + 0x4ef78669, 0xd416225b, 0xf0b0b75b, 0xfe3059bd, 0xb6ee0f6d, 0xf8ff4904, + 0xae489a47, 0xc81348d9, 0x968582f5, 0xef747bf7, 0x64d8ec2d, 0x8de50919, + 0x9bf3e341, 0xd3f58cab, 0x84c5b096, 0xc2a57976, 0x5bfc615a, 0x72ed8c1a, + 0x54b13f9e, 0xdf31674e, 0xf0c5a07c, 0x06575c54, 0xe1e82fd1, 0x3ebb00eb, + 0x87da246b, 0x53df14db, 0xfb05bf50, 0x1e3a444d, 0xe2f9f0d6, 0x07be2965, + 0x997860d8, 0xdf40930a, 0x78dd8577, 0x743cb557, 0xfe183291, 0x7e1c979e, + 0xebc184d3, 0x56fb8588, 0xdc3a21e6, 0x7cf8ceba, 0x7d762849, 0x3bea0f9c, + 0xd03ed34b, 0xbf6daf3d, 0x1d03ed32, 0x9cef54bf, 0x0cafa86d, 0xbfe868df, + 0x4312cb62, 0x9596b2fb, 0x9adbf686, 0x4bea1b57, 0xfa1a7742, 0xbd6ebadf, + 0x8696fda1, 0x37ed0dfb, 0xd4326d57, 0x6e3e0c6f, 0x6160bfe8, 0x795da1ab, + 0xfa0e6569, 0x305af537, 0xfde03867, 0xacacefd4, 0xb1f2894d, 0x1b8ff3e4, + 0xd93ca8b3, 0x3d72a5e8, 0xbfc82bca, 0xeb2f1f69, 0xa0e496db, 0xffbe4b9c, + 0x8d90d2c8, 0xdfcb1272, 0xcb18f2b1, 0x6837c8c7, 0xf3d91287, 0x5005851a, + 0x6e14fbee, 0x77f3e48f, 0xec65fe84, 0x1ab7921e, 0xcd63cb8d, 0x50cbc3f3, + 0x48b46a5e, 0xf1338361, 0xa15dacb8, 0x46d63075, 0x830cace3, 0x9ae81854, + 0x77b3806f, 0xafe699bf, 0x22e3e743, 0x2581f7b4, 0x791fce0a, 0xf186fb39, + 0x297f8f08, 0x48333bd5, 0x5636f62f, 0x22a07da4, 0x7e5402fe, 0xca90b8dc, + 0x2a418d13, 0xa2ac683f, 0x06c6fdf2, 0xd71a7b2a, 0x636ef951, 0x8d63ca88, + 0xbefe54cd, 0xb7ca85b1, 0xf950b71b, 0x9530c6db, 0x54fd1ba7, 0xb5a9f00e, + 0x43fd10bf, 0x432b07f6, 0x0ebd9717, 0xcdc816fe, 0x7737e919, 0xe11afaf2, + 0x4bc22737, 0xe213dd2c, 0x434c858f, 0x89292dd1, 0xc4c923d3, 0xf9c8182a, + 0xfaf6e303, 0x8abaf296, 0xe008032a, 0x0397fbd3, 0x860d22e3, 0xde3d357d, + 0xf683bb41, 0xd93365ef, 0x99f9163f, 0x1e9706ef, 0xd423401f, 0x8474bf37, + 0x35fd029f, 0x7e72f14a, 0x9cbc0af9, 0x8dddbc39, 0x964d747a, 0xa4c1f3c9, + 0x6dabebc4, 0x7538f5cf, 0x1a77d4f0, 0x945a67eb, 0x7a0fee0a, 0x478ee793, + 0x3e78f07e, 0x65ba4028, 0x59c72951, 0x3e79a593, 0x617ec348, 0x95db0f5a, + 0xf105fc42, 0xb6fbf508, 0x4e3448e1, 0x760e8e14, 0x1f27de1c, 0xff713f3b, + 0xfea17c84, 0x9a3f4349, 0x473e5975, 0xff856abb, 0x1401897f, 0xc72ea953, + 0x87376fad, 0xf3e217ac, 0xe0f9865d, 0xf58caf3d, 0x8a1bccbe, 0x427654ff, + 0xa4a807f2, 0xacde22a3, 0x18f769de, 0xa18a75f5, 0xdc39df5e, 0xf8dfd063, + 0x3657900f, 0x5ed15153, 0xe8b608d5, 0x0acd9d53, 0xf90bb7c0, 0xaf52e806, + 0xb6b57ef0, 0x8f082d1e, 0xcd3474ce, 0x3d8bc4bf, 0xb1bd685b, 0x3c6c9df0, + 0xc4d555ec, 0xcf9b57f0, 0xe38811dc, 0xf0ae7f97, 0xc4c6a538, 0x0b665ffd, + 0x584e51b9, 0x873dc856, 0x07399bf8, 0x0b7143f0, 0xcbaba3cc, 0xe9afc071, + 0x7acf678f, 0x8dafdc4d, 0x526ad79d, 0x757f09ce, 0xc2ce8ebb, 0xb1e2c775, + 0xb43ff3ae, 0xcc8dc520, 0xdf894780, 0x6ac04a5d, 0xed57f182, 0xf9434f7c, + 0x2a12d8fa, 0xc4dce7fc, 0xbf0c19f8, 0x2384eb33, 0x7b35ceba, 0xad5fe45c, + 0xede224d9, 0x79c6eb10, 0x13134e97, 0x74bd017f, 0x62e58070, 0x26dfa826, + 0x5dee326a, 0xfe4d51da, 0xa42c87d5, 0x89f53fa1, 0xfd04a5b9, 0xaded5583, + 0x3ce01f9a, 0x88154cc5, 0x4dec53af, 0xbd1d24f7, 0xd11a4c8a, 0xa366b6e9, + 0xa6fe00df, 0xa6fe0ea1, 0xcd9cbea1, 0x7638c4c9, 0xb80b66f9, 0x434eb4be, + 0x879328fb, 0x3582b0e8, 0x7afb446c, 0xfcd263bc, 0x3f0e904b, 0xf104b27f, + 0x479a14bb, 0x8f1e22a6, 0xd6ff1e12, 0xfbe257f9, 0x1bcf0713, 0x7c98dbe5, + 0xed43c080, 0x8e1fc54e, 0x991737c3, 0xfe4abf38, 0x4ff080da, 0x2dcdfa89, + 0x4d6bf531, 0x6b724a8a, 0xe3a46666, 0x642d8f29, 0x5f76a64a, 0x7a12f004, + 0x026beade, 0x12a3fafe, 0xbb226d98, 0x74c0991e, 0x04a8fefd, 0xf2af79e9, + 0x013472fa, 0xc04c8d4c, 0x06d80b3c, 0xd04d3be2, 0x60f08ad7, 0x1aa59cbc, + 0x728f59d6, 0x9dd8e30d, 0xb7df0c1d, 0xf1da637b, 0xc637681f, 0x8e1bb232, + 0x2776c6b1, 0x87f219b0, 0xbe7c67cb, 0x180fc842, 0x4c3be222, 0xebdfa17b, + 0x662339b6, 0x34d94bf0, 0xce2077b5, 0xc878c3c8, 0xfe91813d, 0x645e52f3, + 0xaff787ad, 0xb5847913, 0x4b0d94ef, 0xa97fc21d, 0x84b61b3f, 0xb57574d3, + 0xa97e435f, 0x12c3bb3f, 0xf40df49e, 0x989617a0, 0x279b9519, 0xca236094, + 0xd49bc4ad, 0x3c3d517f, 0xcb97a3ca, 0xfef431ad, 0x03a470da, 0xec70753d, + 0x482d8252, 0xbe3858f7, 0x8359f8f6, 0xadfadfc6, 0x68305f8e, 0xf0f19dfc, + 0x631c7a78, 0x0337a4dd, 0xfee80cc9, 0xa8f3dd9f, 0x8ff7444c, 0x85233e41, + 0x58f84fe8, 0x4b79e344, 0xb8f8cbac, 0x59e5ebaa, 0x81575718, 0xfe05eb7f, + 0x485ac95d, 0x294c448f, 0xb335cfc2, 0x55de0e88, 0xfea6bf5d, 0xff783aab, + 0xfd4ed66a, 0x3119bf31, 0xe1927bac, 0x7def293d, 0x9cd49ec2, 0x1d11612d, + 0x790b763f, 0xe087bf00, 0x106bcf93, 0xb26bcc3e, 0xb6a79a6e, 0xcf30cd3d, + 0xf6735f80, 0xf9d11662, 0x376ab53d, 0xd9ed77f1, 0x019e68cb, 0x6afe067b, + 0xfc6a1b44, 0xa3b80691, 0xc0334fe3, 0x3a7f1d1b, 0xcfc72bcd, 0xca72039a, + 0x2be513f5, 0xc293cb42, 0xb7a7804d, 0x91f7c1ac, 0x9b5cb25f, 0x76415f73, + 0x04f1fa5a, 0x744fc7d4, 0x1d34df6c, 0xea09fae8, 0x9b975c39, 0x739eb9b9, + 0x92174c86, 0x7c853afe, 0x18bfa030, 0x43f1afe8, 0xb7e8c7b4, 0x8c0af851, + 0x28f59a3f, 0x3746dfa8, 0x8e50f518, 0xef84dd33, 0x3e33ace5, 0x019ea2f7, + 0x521b95bd, 0x9f5ce263, 0x6fcfc709, 0x9f4f3e36, 0xc73aba51, 0xd3516e07, + 0x2798a533, 0xba505f4a, 0xb187a47b, 0x7957d40b, 0xe2d299fd, 0x79ff50e1, + 0x1532bad3, 0x7ff4d5fc, 0x86ce2d2b, 0x91b2d3ba, 0xca15abd7, 0xb7cc592b, + 0x89be8594, 0xcac0081e, 0x6294728d, 0x0a9cfc06, 0xccbf9b1c, 0x5fb47a8b, + 0x9e8478e3, 0xd3d19f80, 0x39467e38, 0xfc46ed8f, 0xd67a98e4, 0xc3f973a3, + 0x052bff17, 0xe62f4643, 0x1e0f013d, 0xf483c1b6, 0xbed34781, 0x8ebfc21c, + 0x5f2533f5, 0xf305b14c, 0x4b938e10, 0x167f7ec7, 0xeaa27d3c, 0x5b0dc500, + 0x71f9fe44, 0xf46eb710, 0x326f55bb, 0x3364e3f2, 0x0965d7cf, 0x378ceebf, + 0xfd487937, 0xa195959e, 0x53eae0ea, 0x9fc8ddfb, 0x5f1c5f7d, 0xd6237e8c, + 0x13d08653, 0x32a359f5, 0xa3139254, 0x749e667e, 0xc14aa3e2, 0x5b378847, + 0xb6cf3466, 0x7e510942, 0xc0b5fa44, 0xbf5c1e01, 0x7f31aa12, 0x8edfc179, + 0xe0d6e3a7, 0x775866d5, 0x83c85985, 0xbdb0b98b, 0xf08f2ab7, 0xf6836e96, + 0x6b3d688c, 0xe809cee9, 0x0398a4e7, 0xc37be2d7, 0xc6cd9f97, 0x43d98e7a, + 0xb4a2dbf8, 0x00f8470c, 0xc3cfb48f, 0x569d82f6, 0xdcc93168, 0xcf26f64f, + 0x69ce2219, 0x1f4acc6b, 0x55cf2fca, 0xde718b83, 0xf7bebdfc, 0xf1fc619b, + 0xf70f9a95, 0x9bafc65b, 0xccf88e99, 0xc03d7132, 0x72f390ee, 0xf82f5f3d, + 0xf8aacfae, 0x77ded0fd, 0x8435a7bb, 0xda0b33ed, 0xb519afd1, 0xfdc3ebce, + 0x42873e80, 0x7a35f7ef, 0xe7282f29, 0x1c95dd1d, 0x9e49bbb1, 0xf3c8373f, + 0xd07d633a, 0x3b7a5f7c, 0x7fbc707b, 0x9c42f8f6, 0x1d0f949e, 0x67d9e82d, + 0x725dfbe6, 0xb42cd1be, 0x7391fd1f, 0xcc5fef9d, 0x7fda74ae, 0xba037410, + 0x925e9084, 0xfbdf402e, 0x121b5f10, 0x78bef7d3, 0x6b6e5df4, 0x5db946c8, + 0x659f6815, 0xe625e781, 0xafd883e0, 0x21f76166, 0x50decd0b, 0xe927fc88, + 0x70d0d4ce, 0x740353d4, 0xfc21497f, 0x7c717667, 0xb7361fd6, 0xcb1e7ee2, + 0x40b7ae0a, 0x42ca99fb, 0xa22627ca, 0xfe75f8f3, 0x017cbd74, 0xfce2b7dd, + 0x9a8ebbe3, 0xef493e10, 0x49de44c7, 0xffecadca, 0xbdfa598c, 0x0f76be62, + 0xfc55f7cd, 0x166eb457, 0x7c780b8d, 0x80dfcf56, 0xff9c76c7, 0x1fe166c7, + 0x3b63c60f, 0x3c073ff6, 0x3c1739ee, 0x939de87e, 0xcfe30799, 0x7f093b32, + 0x87329f2b, 0xbea4b0ad, 0xf52fd2d9, 0x333c335f, 0x5e5627aa, 0xd71fb0d4, + 0x8549f2b9, 0x6bb2acf8, 0xc26c35c5, 0xf96378e0, 0xe3e910c2, 0xd903b8d8, + 0x5ab2f912, 0x7f13178e, 0xff07b354, 0x734e4cc3, 0xf54ef498, 0xbffb634e, + 0x9b30f945, 0x24ce04f2, 0xf1b1b79e, 0xf1d0b2f1, 0xe248be47, 0x8b26717c, + 0x619e1c91, 0xd0f7c429, 0xbb608bee, 0x33fca2e6, 0xdc6291db, 0x314cac9f, + 0x6e8e4fec, 0x4ff21930, 0xc9b1f3b1, 0x5fec4cca, 0x6730e42a, 0x6fb0c99d, + 0xee321b97, 0xa737e5eb, 0x5a63ea1a, 0x9ffa1846, 0xd0cf25b7, 0xbe7c2e3e, + 0x9d82fda1, 0xf1f50d13, 0xfa1b17ed, 0x6659d85f, 0xae4717a8, 0x749ff432, + 0x3ea18e78, 0x4326fba5, 0x2f6fa9ff, 0xd45fb435, 0x7ed0cab3, 0x0c6bc7c9, + 0xeffb4bf5, 0x2c8ff432, 0x00ac38a9, 0xff025efd, 0xe086f314, 0x67c8a857, + 0x99acfe07, 0xfc0e4f90, 0xa8c4d0b9, 0x2bc867dd, 0xa673f81e, 0xf81f9f1f, + 0xfb1f8973, 0xe7cb3295, 0x5952e2f1, 0xdb19b0ce, 0x0be05553, 0xc0d96fb4, + 0x569a9817, 0x7203f28d, 0x39454235, 0x0fc3a7fb, 0x469d0215, 0x46482cac, + 0x34f20d3b, 0xbd373d42, 0x27ef8394, 0x962da792, 0x290f1b96, 0xac7ded83, + 0x38e590be, 0x5bade655, 0xbad37de8, 0x65a7616c, 0xb230f17d, 0x5f9f9233, + 0x7a1c5333, 0xe3d70366, 0x86a43667, 0xdf9efef9, 0x0fe75c39, 0x24e8399e, + 0x9efdcefe, 0xaf01db93, 0x892cebd3, 0x7f2901da, 0x323f22f9, 0x7945582a, + 0xe3fe418f, 0xb8f59ea2, 0x1ff573ce, 0x99c6fd63, 0xff021e92, 0x05d1d709, + 0xf1f68972, 0x27da1483, 0x7161e35a, 0x36b6eff7, 0x16770f36, 0x4b2e7e0c, + 0xdce1cd65, 0xb40f30fb, 0xe159f14f, 0x1fd86dfd, 0xbc587bec, 0xb5ea26d7, + 0xbd454d21, 0xebe22b56, 0x521e71d8, 0x7e466f4b, 0xdd96a1d8, 0xc5d14eac, + 0xdc5a0dd3, 0xd077c7bc, 0x0473c089, 0x0d80efaa, 0xcf5fefe6, 0xff306d7c, + 0x0ca78b1a, 0xf4ee6beb, 0x9af21d12, 0x7ae1667b, 0x5dc13a73, 0x73fbd9d7, + 0xc056a780, 0xd4f08b53, 0xa714fda9, 0xb0a8bff5, 0x879c5cb6, 0x5f66bb8f, + 0x487e432e, 0xd51ce704, 0x72057c42, 0x738e3770, 0x4ed09aa7, 0xf28e7ddf, + 0x638d5eb0, 0xf2ec065f, 0xf15bed52, 0x137072c7, 0x9eb44a78, 0xe196d0ff, + 0x9d39b728, 0xc0a89fa5, 0x60e039b7, 0x9f22a726, 0xd1bef632, 0xebef623f, + 0xf344d0fc, 0x7689557e, 0xf1157def, 0x0631f7ce, 0xc7231dc1, 0xe46f75de, + 0xebe9a417, 0x4c17e7af, 0x10950012, 0x306c14bc, 0xe5e2db88, 0x95f6738b, + 0x2427561e, 0xbdefe786, 0x377881ce, 0x4bfd5e46, 0x7c8f5ec7, 0xb311fb77, + 0xb2845562, 0xc84178c1, 0xe677b2eb, 0xf0e8a664, 0xe5b1b5b3, 0xaf27556a, + 0xf7f012a3, 0x9ff72a9b, 0x5c3635b6, 0xe380595d, 0x3d7a4c7a, 0xca13dd90, + 0xd27988dd, 0x8c2f870e, 0x9327acfa, 0x702b58f0, 0xbe0a6c90, 0xf4bcfc89, + 0xd7ca6ec2, 0xe97c88e6, 0x297e7168, 0x2ae3be76, 0x97f847cf, 0x8c2958da, + 0x16cda7fb, 0x34b277f2, 0x08e28798, 0x5a5b9d07, 0x0a6c0636, 0x93db2fb4, + 0x0c53f5c6, 0xd0c6e15c, 0xa20a1bd5, 0xc71c02f3, 0x3dbc1e51, 0x7f3859c1, + 0x4451c22e, 0xe11276f2, 0xe84d48fb, 0x473c9dcf, 0xd21beb79, 0x43c6c4fe, + 0xf0e2fd09, 0xa7e485fd, 0x7e4dffe6, 0xa1c3fa31, 0x0c3fa8a2, 0xd058b2eb, + 0xeb8c594e, 0x8b55d9d2, 0x95d6dce5, 0xaeda1964, 0x92416e3e, 0x32407389, + 0x9ae1230f, 0x57f2e169, 0xe618d1ef, 0x4e51ead3, 0x54d9f0e3, 0xbb88628b, + 0x3138adbf, 0xede6553f, 0x7887bda4, 0xe5c2e311, 0x33a3e24e, 0x0bfbd6de, + 0x877c7327, 0xc8f7c086, 0x04322375, 0x0f887d5e, 0x16f1c789, 0xbc069ea3, + 0xb5e2e2fa, 0x326af006, 0x57ca75e0, 0x95fc95e0, 0xa98f9daf, 0x9cefee34, + 0xa5dff816, 0xde703304, 0x5bbc3753, 0xbab0f982, 0x086b9f79, 0x679ed7d7, + 0xe7e9b32e, 0x981ef991, 0x9cf383c7, 0x9aafe1be, 0xe825a7d0, 0x39ed3667, + 0x35cf192f, 0x93f38ad4, 0xfd5af6a7, 0x3e5f8e8a, 0x1e70f2fd, 0x1b4fa5ea, + 0xf2c7ccaf, 0x5bcf2a54, 0xf53bda9e, 0xa9d5f210, 0xb12d1c9f, 0x9ea738c0, + 0xd2a25a3f, 0x60d85b3e, 0xef2f6a7f, 0x203b412e, 0x7c03daf3, 0xdfaf8b67, + 0xfcfe0b56, 0x4aafebda, 0xc8d5e788, 0xef1ca707, 0xebfae096, 0x0f09675c, + 0x7cb9db0f, 0x6da1923c, 0xd32332c4, 0x17fa10f4, 0x4fc1a45a, 0x5b8788db, + 0x75265822, 0x7971fbb7, 0x23bbb7ce, 0xfa7bba58, 0xbd7618fd, 0xe201fe05, + 0x67b1f3d5, 0xbe1fd63f, 0x33e504f2, 0x1ab017d9, 0x80916380, 0x3b59f7e3, + 0x3a04a91e, 0xf37d2efc, 0x7e86e423, 0xf685eb01, 0xa0dff19b, 0x1e818e87, + 0xdc6c80f2, 0x7cfb72a4, 0xb512a553, 0x191ff853, 0xe9187947, 0x8a3545d3, + 0xeea5aec1, 0xd3f94199, 0x6429af3e, 0x61a47581, 0xbff81a56, 0x66ceeb4f, + 0xc5cec0df, 0x3883bf96, 0x9d9d7de5, 0x0952acfa, 0x67df30a9, 0x7fac8f42, + 0xd3f1127d, 0x178a65e6, 0xfefb18f1, 0xcb5eeb63, 0x727a099f, 0xf3879dd8, + 0x6efc8267, 0x90027916, 0xa7cf0537, 0x80f22c3d, 0x877b866b, 0x9ae3ede9, + 0x8252f323, 0x46defaba, 0x89d6dfbe, 0x7ca15ee7, 0xed7b9c41, 0xfaa2cc6a, + 0x2a5e8d4b, 0xe9638d23, 0x434b66f9, 0x7bdf9e0a, 0x3342c2cd, 0x77bf97c1, + 0xe51bff78, 0x1ddb42e0, 0x699b2fbf, 0x33d6f187, 0xd6f8cf3a, 0x13ddefbd, + 0x1df00e9a, 0x1929a4f8, 0xd2a740ed, 0xa61c478e, 0x23fdbe2a, 0xcb5d4f51, + 0x75a54f48, 0x306e742a, 0x3611cbad, 0xb7d3fce9, 0x765edc2c, 0x72de785b, + 0xb442da2a, 0x7fa5b32f, 0xef413fd7, 0x0fea0cc7, 0x7b9e1f81, 0xa98f9d8e, + 0x4ecf94fd, 0x7c30def4, 0xbfb9fc6f, 0xad4c77d7, 0x2a89f3a0, 0x66a77fb7, + 0x903eb667, 0xcfebfbcb, 0x79e1f497, 0xfa7238ce, 0xbdef3117, 0xc7f74e16, + 0x64768d72, 0x8fdb9597, 0x1df316ff, 0xa392dc68, 0x9651bf3f, 0xffe8dfc0, + 0x335ff2a6, 0xe488ff68, 0x68f596be, 0x3f72bcfc, 0x11fc49e5, 0x3619af8e, + 0x577d470e, 0xca04b2b1, 0x97ae4e19, 0xe50eb0d2, 0xeb9c550c, 0x689cfc66, + 0x2b56455a, 0xe28e5f9e, 0x5a73af81, 0x1c16bf4f, 0x7dc3dfcf, 0x7c0fb4df, + 0x29ebf20a, 0x7fee39a4, 0xfd11b6cc, 0xaa825b67, 0xbc52f486, 0x9d22578f, + 0x3a238cf6, 0xec958fd9, 0x5c3a464f, 0xde4cf2cb, 0x2dec1f28, 0x9c627a05, + 0xb6f14fb4, 0xa73ee8b1, 0xe340bf9c, 0x23e595f8, 0xc877e04a, 0xea5a05e7, + 0x784fdc0c, 0x82581ec4, 0x7e113247, 0x678c165b, 0x478cde0f, 0x5debedd2, + 0xf4e0154d, 0x3b40b5ed, 0xba360bd4, 0xfe00369b, 0x4704a6f6, 0x6b9796e2, + 0x30e9a3bd, 0xb970a7b6, 0x68e8d828, 0xd1c8b942, 0xe61f3c3c, 0x5f22e7f4, + 0x503dd40d, 0xdbabaf1f, 0xaf2aea62, 0xbed575cb, 0xc843e7fc, 0x5c5d75a7, + 0xd6f006be, 0xfea0ac59, 0x7e135f3c, 0xf4398392, 0x547fddfb, 0xbe341382, + 0xedc85d8f, 0x4a07dc98, 0x81f62ed0, 0x828b58b2, 0x1e04767a, 0xff47cb60, + 0x6cca9bba, 0xdca54fd6, 0x59dbc8df, 0xea04607c, 0x76605353, 0x35e7d239, + 0x18f7970b, 0x72b1efbc, 0x2d6bdd3e, 0xf985659d, 0x63d01e1e, 0x46ba5f7c, + 0x81b669e8, 0xc15eedeb, 0x9b369fbb, 0xc9c01a42, 0x79e83876, 0x553f388d, + 0x4c81cef3, 0xd4f8d7dc, 0xc9e22acf, 0x7b085cc5, 0x5b5f8f11, 0xb946822e, + 0xef907fa8, 0xcc7c819b, 0x21d57c45, 0xd937505c, 0x847ce9ba, 0x87f69ee5, + 0xff3718cc, 0x73c1e2d8, 0xbeb9d58e, 0xa2fe78fd, 0x0fae5f7a, 0xc3bde555, + 0x9d577c79, 0xd1399ed2, 0xbacbe519, 0x21d94dce, 0xfb27f7c0, 0x95f2477f, + 0x61ec878f, 0xa38edafc, 0xd79e105a, 0xa1a7bc75, 0x4524fd61, 0xda3e81fa, + 0xb877bdb7, 0x9c12f92f, 0x3c6657ef, 0xa7803859, 0x14ee96d1, 0xc3c979fd, + 0xa0fde7a0, 0x3d035fcf, 0xd021e58f, 0xf3d07eff, 0xd7f8be47, 0xaf3fd44c, + 0xccd7c25a, 0xcd9e71c1, 0xe15e60f7, 0xc1f84f53, 0xb4ff5089, 0x3d6f8c60, + 0x6b3e57d4, 0x7fbc600e, 0x96716d44, 0x6083ff40, 0x9dfde847, 0xc2f4eaff, + 0xdb0583f3, 0xf471bd33, 0xd36795dd, 0x60981f99, 0x7cef997b, 0x36078f94, + 0x976c9bfa, 0xbeb9f802, 0xea18ac55, 0x0d93795a, 0xa99365e4, 0x1f62d1fd, + 0xc73867d5, 0xce597f81, 0xf2b187e5, 0x278e52a6, 0x71b4dfaa, 0xdfdc0cd3, + 0x8a7bbb5b, 0xc89a7c82, 0x7d9d56de, 0xc825ce8e, 0x6b263e7a, 0xd4aaef80, + 0xaa59e510, 0xce84fece, 0x271acc33, 0x61fe68f3, 0x1f2dc68c, 0x8edd7886, + 0x13177c7b, 0xbdf843c9, 0x68b2f6c2, 0xabc1f51d, 0xd0be02a9, 0x41334d8d, + 0x0cb11fbe, 0xdcf1fbb4, 0xe12b9aa0, 0x523c2167, 0xfb26aafc, 0x099a6e2f, + 0xcd76ea41, 0x36867e38, 0x02afdfd0, 0x249abe1f, 0xfc682beb, 0x6293fd41, + 0xf1c997fa, 0xf3c2e3eb, 0xb75a3d88, 0x2ff57f41, 0x59fbe8d6, 0x3b68ff88, + 0xc727978d, 0x56f0475f, 0xf6f3370f, 0xbf65e850, 0x4dcfa51a, 0xeb4dfdda, + 0xdaaf6f01, 0x97a8a57d, 0xa465affa, 0x7cff916f, 0x49b87e3a, 0xb3aad9e8, + 0x39fd3157, 0x58b49b92, 0x90c75cba, 0xde3ee76e, 0xa2f186f9, 0x7a604ce3, + 0x7e047ffa, 0x6fb7584d, 0xedd762bf, 0x03ce90b3, 0xc510b3f3, 0xf35b55f3, + 0x07a75859, 0x5f1c3ffe, 0x027f0e17, 0x5ffe6638, 0x61ac6386, 0x451c28be, + 0xfefef806, 0x80259470, 0x02b7d663, 0x959dac47, 0x67617ee5, 0x0d5452fb, + 0xbdb63bf7, 0x8ffda564, 0x96c85374, 0xceba7687, 0x5b7a7644, 0xbf1f8b6a, + 0xc6b6d8bf, 0x1ee1e74b, 0x722a04b1, 0xdd0a7fc1, 0xabfda269, 0x6ebe796d, + 0xf6dadfdc, 0x26be792f, 0x8b3d349c, 0x071662ec, 0x3c5b6d81, 0x087e2aff, + 0xa3efef8d, 0x3e3b44e9, 0xf646c532, 0xe59cdb72, 0x9f4fff94, 0xda1c7673, + 0x0a7e9d49, 0x66531d91, 0xf3353f93, 0x3c26d6be, 0x149191ef, 0x2ffd1c78, + 0x74dad425, 0x76bc7878, 0x58667fae, 0xbe6066db, 0xcf595b68, 0x73938c38, + 0x803e702e, 0xfcf5abaa, 0xff311311, 0xbc1adc73, 0xbb780ad6, 0x1bf22aca, + 0xf2852c29, 0xc9051562, 0x6dd2c2a8, 0x5a253ed0, 0xa7caf87f, 0x3191cf29, + 0xefc860af, 0xaf814b18, 0xa67a3abc, 0xf641ffa9, 0x461afeb9, 0x8bf47179, + 0x172feff5, 0x027d7d7e, 0xb4e81dff, 0xad1ce11c, 0xd4c21cf4, 0xd1e75d61, + 0xd45f18d9, 0x139955ae, 0xe46d496c, 0x8bffdc77, 0xfd6207f1, 0x22de595a, + 0x7c44acfc, 0xf3958cf1, 0x25ff80e5, 0xe40fadfc, 0xb3f0a37e, 0x1ea2ed2a, + 0x9e506e73, 0xfe13ec17, 0xfc62df4f, 0x37d61268, 0xd769978c, 0xee7ce904, + 0xe5deb172, 0xd1334a5b, 0x7fdca9bf, 0xd963ad23, 0xf7e4d9e6, 0x84bcdf2f, + 0x784a7bce, 0x9bfc632a, 0x51265acf, 0x1d112bbe, 0xfd221fa4, 0x273f5899, + 0xde157bd1, 0x41cfa256, 0x58edafcf, 0xe67cc36e, 0xf67fa8c4, 0x7367c42a, + 0xf1a6dca0, 0xb31e09ef, 0x1b6d38f3, 0xb6005f7e, 0x399650ff, 0xb957d715, + 0xdf092329, 0x716b623f, 0xf91e5ca2, 0x61d7d7e2, 0xf093f43f, 0x9529ccbc, + 0x9eb2a5fb, 0xb72b9e08, 0x55e93f70, 0xe1accf31, 0xeff3661f, 0x1879c4ab, + 0xe97ca696, 0xec7efc48, 0xa69d9879, 0xaf903bb2, 0x9d7810ef, 0x873e0b62, + 0x155793f5, 0x5ea79f12, 0xc7cdd079, 0x79d79e37, 0xd3a5c44c, 0xee4dc3fb, + 0xbfdf3a74, 0x71e5e1db, 0x23ac1946, 0x653e4fed, 0x7f1e8ea9, 0xaf8978b1, + 0xc528fe31, 0x47d7a438, 0x702ce0f1, 0x0579f82f, 0x7e48df23, 0xa6f3eafb, + 0x2dff066d, 0x69f4de7a, 0x8b4edbf2, 0xacf5e5b8, 0x724be6c8, 0x51ef6c31, + 0xdebd4e31, 0xbf416e99, 0x16bcc030, 0xf5ae4b8c, 0x16eb9cc5, 0x11aedae7, + 0x7dc209fa, 0xfa0daefa, 0xaf15f619, 0xcfac669f, 0x37eb1bf6, 0x7effc454, + 0xee374d8b, 0xdf169fdb, 0xf0299e75, 0xb10ca726, 0x002d82de, 0x3bbd6eb4, + 0xae127f54, 0x9bcb4777, 0x26fe7d6e, 0xb0584f36, 0x4f212345, 0x900eee34, + 0xbca43c0f, 0x9d688580, 0x99dda94f, 0xc0a0b8fa, 0xb579ce22, 0x12f33aff, + 0x36c391a0, 0x9fea266c, 0xe7eb955e, 0x4afefbbe, 0x4b18ebf1, 0xcefc0de4, + 0x168bcc78, 0x2853ee2f, 0xff285a2f, 0x4edb3f51, 0xa5bf03df, 0xf7a1935c, + 0x3900c7c7, 0x5d33ae10, 0x5f3c8663, 0x9bacf73a, 0xb79ec5fa, 0xe7cdfbff, + 0xcec73c24, 0xe23e5ec7, 0x16007bc6, 0xf9d1366c, 0x5c8b85ab, 0xa4889df4, + 0x6338ec6f, 0xe171a8b6, 0x84ff844e, 0xb8f4b774, 0x74e6ff71, 0x4af299bb, + 0x6de3edb1, 0x5f8b37ca, 0xbaf31a17, 0x43fd9ea7, 0x57d60461, 0x375cf4ab, + 0xd8e2972e, 0x638c36f1, 0x5f719d37, 0x3fbe7a49, 0xaefba033, 0x86fdb7a9, + 0xe3cf20a4, 0x4903be18, 0x2f128fc4, 0xea70f089, 0x7e16edf0, 0xd164327e, + 0x28c6d7e7, 0xef9439fe, 0xa7b2a4db, 0xd1a77ce2, 0x7be71364, 0xc44c9ed5, + 0xfda5dd57, 0x2f2ab714, 0x41eee87e, 0x7ef160bd, 0x23e0e29f, 0xe97b0710, + 0x3c775efb, 0xfc1bfdfb, 0xc4ec10ee, 0x8fb71b02, 0x12f3edb1, 0x17f8a39c, + 0xecdf8741, 0x9bd1e4ff, 0xd013e087, 0x6f30733c, 0xd551ef35, 0x3aaef983, + 0xdbc90f4b, 0x3718affc, 0x76fc7f11, 0xa0f29dbf, 0xe9da160b, 0xf9d888fe, + 0x8f3dab4e, 0x9df30cde, 0xff707806, 0x00a8f4ff, 0x66f4f1e1, 0xf6fb83d5, + 0x983ae7f3, 0x54ffd74d, 0x08f9f1c7, 0x0cce99df, 0xba701f3a, 0x49df3e2b, + 0xfb655d3c, 0x45c57986, 0xf209fcc6, 0x8eadca1f, 0x3c57feff, 0xc70abbfe, + 0xd7e1c29e, 0xd53a8b9f, 0x8f1c9f91, 0x7c1f72ae, 0x1cf18b4c, 0x2ee80955, + 0x775eb71e, 0xb180acb0, 0x0c8eb261, 0xa075f30e, 0x7071e39e, 0xfb24f104, + 0xdd7cd43f, 0x8577dc4c, 0x03f11fba, 0x9d5bf9ef, 0x7762bfd4, 0xe8cfc211, + 0x059ab9bb, 0x3b01e64e, 0x74a399f4, 0x54f00db3, 0x43407dd2, 0x6475857f, + 0xc46bfad0, 0x6ef0b1fb, 0x68fd8bb3, 0xe4ca87bb, 0xc23ffdb7, 0xba3a4a7b, + 0x49f8bc93, 0xfc6a4756, 0x5d9a0073, 0x60039c31, 0xf1e50f6a, 0x3cf06632, + 0x473eff6b, 0x87894db8, 0x3bfcf59f, 0x2abb18af, 0x8d46b7e5, 0x11ad7d90, + 0xe6abf5f6, 0x5bdf10ef, 0x9ac492be, 0x355df46d, 0xbfe013e0, 0xb41717fe, + 0x7af9403d, 0x1cac9dfe, 0xf31164a7, 0x47fae9b7, 0xe33cf26c, 0x833d7cc3, + 0xbd70e7de, 0xfb033a02, 0x4cf6a667, 0x01bff250, 0x7e316e1f, 0xeb6b5267, + 0xf43d4429, 0x15fc1284, 0xedfeadd2, 0x77ac4c9e, 0xfc9279bc, 0x67c573ae, + 0x7f3205ee, 0xeed0d114, 0x3a5dddac, 0xb57f286c, 0x9d40e306, 0x7de28c7e, + 0xf187c516, 0x5abcc3c6, 0x2c11d9cd, 0xdd143694, 0x126859b2, 0x9fdf33c7, + 0xdf8099e8, 0x6e3ac1ef, 0x2ff5039d, 0x3fccf462, 0x69e9fc2a, 0x574cffdc, + 0x730d41d9, 0xdd376a6c, 0x214bf0bf, 0xf214bf2f, 0x33dff1d2, 0x74fa46ae, + 0xdcf269bc, 0x97e3ab93, 0xc1b21624, 0x7b5bd77b, 0x8efe827e, 0xebf6cbac, + 0x869d2fc1, 0x72e36afc, 0x66b5e523, 0x7d397c51, 0xfe26e6d2, 0xc476f61c, + 0xc7ce798d, 0xff23e951, 0x7f271fb7, 0xccd3a3a1, 0x61cd93f0, 0xa0e6828b, + 0xc1ff8a33, 0x2a3d70e3, 0x96a21de5, 0xde425c0b, 0xe57bdf91, 0x951e59f7, + 0xc2b5c7fc, 0x3c65ec7f, 0xfb11a87e, 0xf02a7fac, 0x1afe39d3, 0x5c600b3b, + 0x3f8f27f7, 0x78fc8539, 0xdf2d9fa3, 0xbdf67e93, 0xa55e39eb, 0x38a362de, + 0xf266647f, 0xaf296bfd, 0xf687ab2c, 0x207f24b1, 0x03d3c4ff, 0xd47a0a97, + 0xe819359c, 0x46a7a51a, 0xdfcf94f4, 0xd2127b07, 0xfa5cc39d, 0x377d0171, + 0x51f31b73, 0x66b6e33e, 0xe4e90b07, 0x3e51e3b6, 0xc63dc76f, 0x798967f9, + 0x3e38925b, 0xf877c43b, 0x91dfaa1d, 0x37d5145a, 0xae075f80, 0xabcbfd4f, + 0x79498f14, 0x95dce390, 0x7ee1f7c4, 0xadf357f1, 0x2bb67db2, 0x76a5deba, + 0x2f24b7d3, 0x27de437e, 0x24999f8a, 0xc5e58947, 0x92f215f3, 0x4d05f84e, + 0xf97b46ea, 0x9f1ff09c, 0x68aa6c3b, 0xdb7fc38b, 0xe73d7c6d, 0xec01a867, + 0xdb844177, 0x32fd44b3, 0x15f9c553, 0x3c589781, 0x3fc7e7a4, 0xd056b2ff, + 0x7f8ca6a5, 0x22f78ccf, 0xca0c3e60, 0xd78c1f6c, 0xd10ce65b, 0xef22cbf3, + 0xcd493ee2, 0xca2f56f3, 0xf6f3ef6f, 0xf49bcc2a, 0x6aad6f3e, 0xc7a60e73, + 0x1e8d6fe6, 0xebfd6f7f, 0xf42bf49f, 0xbecd3b63, 0xf3c1de31, 0x845dd927, + 0x93bd019f, 0x68d83fc0, 0x3b3c7273, 0x792d9e38, 0x5ba78f5c, 0xb1ff788d, + 0x33748790, 0xd7a0b644, 0xfe7905a6, 0x90bb39e9, 0x5b87900f, 0x4eec2f90, + 0x2c7efe03, 0xafa969fc, 0xc6575f1e, 0x7ee1a78e, 0x6ff6886c, 0xc91f7e3b, + 0x4b7a79c6, 0xb56fdfe3, 0x6309f05b, 0xea6eff46, 0xfb42af4c, 0x678aede8, + 0x9ff68b0c, 0xe7bfceda, 0x061ddb35, 0xf02cdbbf, 0x7638e521, 0x3cc40f9e, + 0x90cfa81d, 0xc31ece2e, 0x03e4bb3e, 0x7ae4d7a9, 0xfd911da4, 0x67f82f7e, + 0x8ccfe0ba, 0xfc1f3e26, 0xca9ac2b3, 0xdeff01ed, 0x7841eb9d, 0x9da2b21e, + 0x78f34160, 0xaddd67a0, 0x16f7d18c, 0x33fc1f62, 0xbb2df047, 0x07e81d6e, + 0x7e16fe92, 0xd738875f, 0xd407fd28, 0x7a9d134f, 0x0e1c43b8, 0x55f5c2b3, + 0x70927e8c, 0x7cfc3ac0, 0x138d171c, 0x8edc6fb5, 0xb58f42a9, 0x6322ef8a, + 0xfe7fe6e5, 0x569b911f, 0xe9025e71, 0xbcdf4f10, 0xc96eec25, 0x0562fedb, + 0xc04c6bf8, 0x624fc3e9, 0x1ce7ba4a, 0xb0bd40b0, 0x37cb414b, 0x82855720, + 0x45bc70df, 0x18f8a3e3, 0xf032e49d, 0x3e2a3fdf, 0x0366df0a, 0xa3a2dff0, + 0x2e2494e7, 0xf32a19c7, 0xc3fedf13, 0x80381fc2, 0x00d4efdf, 0xdf34505d, + 0x969bf01a, 0xbf4763dc, 0x43e66de7, 0xfb74e9bf, 0x8c78d312, 0xbf70b75f, + 0x6e2f4065, 0xbd07ebe6, 0x6d7a8ed6, 0x477edbcc, 0x2167d411, 0x5bce30fd, + 0xd379f8c4, 0xe3185776, 0x198f2925, 0xe0667b73, 0xa39d473e, 0xf75dbd61, + 0x277fa07c, 0xca8dcff4, 0x35ca0d75, 0x82b53bcc, 0x2b4eb3b7, 0x8b160fdd, + 0x47bec62f, 0xeff226f3, 0x7ae24c6e, 0xd234f50d, 0x6ec21ca9, 0x4afdc03b, + 0x798cc86e, 0xe4c657d4, 0x957dc44e, 0xa2c14943, 0xa67ef035, 0x29983738, + 0x26669bce, 0x126b72f1, 0x0e99cbd7, 0x5c1d065e, 0x79ba67bf, 0xef79d8ff, + 0x54defd12, 0xed7f064c, 0x7c3c8204, 0x38af9f30, 0x327e88cb, 0xed42bf4f, + 0x8002cdff, 0x9997456f, 0x4d3b07f2, 0xea24fac1, 0xfb1d12a7, 0x0f8b3d4c, + 0x1ef10123, 0xf3128ba5, 0xb167d493, 0xa3ea34fe, 0xfcf20d9b, 0x3be3825d, + 0x9190afb8, 0xfafcbfd8, 0x027e7d7c, 0xb7c26b7f, 0xfa496fe2, 0x8c80bccb, + 0x307f25bf, 0x6bad20f6, 0xbfce4cea, 0x6177afa0, 0xbafa0afc, 0xebc91a68, + 0x6bbc780f, 0x719178e3, 0x4f66667c, 0xc0b7c61d, 0xbc9ef487, 0xe4f729f7, + 0xe41e749b, 0xf537248d, 0xb7f0e5db, 0x5bc9c526, 0x6869a88d, 0x8487fba2, + 0x42f795dd, 0xafdf6a8d, 0x19be3aa8, 0xfee1c555, 0x60c59269, 0x7d443a17, + 0xd3971277, 0xa5115551, 0xd88dfa00, 0x015143ba, 0xfced119e, 0x0688f77c, + 0x0c9ff746, 0xf0e61bcc, 0x95870d8e, 0x70a28adb, 0x17669b37, 0xe69e0079, + 0x09af874c, 0xe0ce699e, 0xcd77080b, 0x039d08b1, 0x5bac7a9d, 0xd32978c5, + 0xf205ffe9, 0x6bd7849b, 0xbcc08cf6, 0x8718e3bd, 0x9fc065b3, 0x79e6c9ef, + 0x3c0aefc9, 0xc9fb09b7, 0x4efdd30e, 0x336f6e4e, 0xa6db19ef, 0xfd26673f, + 0xccd7e858, 0x72e3ee28, 0x614f799e, 0xb8ba03db, 0xb03f3cb1, 0x0f979f03, + 0xbf11371b, 0x307fcfb7, 0xc73ee2a2, 0x154d5b0b, 0xf6fc38e1, 0xa75394b6, + 0x2eb8d7ff, 0xc957ff09, 0x4967ec87, 0x1def9a1a, 0xb7060f82, 0xa5ed443f, + 0x84dfa64f, 0xd06cd6f0, 0x48f16e18, 0x033a67bc, 0x239f1027, 0xc4155bda, + 0x9f8e63c9, 0xae0e7828, 0xce798aba, 0xaef6d203, 0x7bc1cb6b, 0x7cee6a97, + 0x79ef072e, 0x38c0f092, 0x98d6ef84, 0x0fd28b73, 0x67e11ff9, 0x67033b94, + 0xcebafc70, 0xb7bfb44d, 0x5fbf0772, 0xcfbae127, 0x9eb02f11, 0xd5bfc8f5, + 0x5478bfc0, 0x8dfb0147, 0x6859acf4, 0x6a26efa3, 0x63fe7176, 0x18f0b41b, + 0x8eefb7ac, 0xe47da098, 0xa61f7edd, 0xed77abef, 0xf0e99656, 0x4c26b235, + 0xb9e77bfb, 0x97227ee4, 0x4bed11f7, 0xb38f886a, 0x63e43e1c, 0x71d92fcc, + 0xfdcecf3f, 0x1e52deaa, 0x425af49f, 0xafd0bd63, 0x87c93737, 0xbabd3bdf, + 0xdefa0afb, 0x35bcf5d0, 0x7ca3b8a2, 0x6f7ac0f3, 0x40f9c229, 0xdf20f339, + 0x835fde80, 0x2726f2f5, 0x1a9fbe43, 0x77a9c743, 0x3bf6be73, 0xc31ef2dc, + 0x63d7c889, 0x81aedc1d, 0xeebf205d, 0xf3c38590, 0xdd74e33c, 0x75c8149a, + 0x87f7e064, 0x54f18611, 0x86bb454a, 0x387608f9, 0xbd5bf095, 0x37d683b5, + 0x7bf71772, 0x92b577aa, 0x82fd4a3c, 0x7b7bc0f8, 0x457be2a7, 0x47040fc4, + 0x943b93e9, 0x927fd0e3, 0xbcf3ccc3, 0xc7ec775b, 0xf019887b, 0xd02fc60b, + 0xce4affbe, 0xe96e2a3f, 0xce3dc80d, 0x59e7c453, 0x097b93a6, 0xbff91c77, + 0x1e77e118, 0xe5c83eeb, 0x6fefc23f, 0xe921fc12, 0xf5c1c330, 0x21c7a48f, + 0xe300e80d, 0xa24bca1c, 0xa23ca471, 0xfa11ccfc, 0xc68ce4c9, 0x090e1249, + 0xd9472ee7, 0xb8298e15, 0x775a6eee, 0xe09556ed, 0x0502d72e, 0x3b7c75ab, + 0xfbf9c1cf, 0xb57782c0, 0xf9be781e, 0x9f0947e7, 0x3f0a2db5, 0x5472dac7, + 0x3e7a879b, 0xe319acf4, 0xff19ab9d, 0x51cf747b, 0x7757cfd2, 0x76d7bc70, + 0x736f56ec, 0xf728f946, 0x74c581e4, 0x95bb751f, 0xe9923fa1, 0x788cde0c, + 0x024fc418, 0x25cf520f, 0xf4871392, 0xf91a4253, 0xe421e029, 0xf520dc62, + 0xdf1156e4, 0xfe7f2730, 0x515d624f, 0x41ac10fd, 0xf927947c, 0xdf50d80e, + 0x3ce8544d, 0xe933b487, 0xf51e3833, 0x37bdc4f0, 0xd287e64f, 0xb25f8c98, + 0x63bee8e7, 0xe2b7d018, 0x5d04bbfd, 0x3f8479e1, 0x37687967, 0x74b1dc25, + 0x6bf081fb, 0x1351f0e2, 0x476b1fc2, 0xfac05f24, 0xf73db19a, 0x41ec89a4, + 0x86d6c86d, 0x98af26fb, 0x75df90e6, 0xf09b8160, 0xdf90b357, 0x67f9bc63, + 0x84d4af5c, 0x777f749c, 0x256e704d, 0xdba543ed, 0xc50fb87d, 0x79b50782, + 0xf774c1ae, 0xce9fbf3e, 0xcedd5c31, 0x8f4060e5, 0x4bfa73b6, 0x1fd72efd, + 0xcfc7375d, 0xec858d2c, 0x6dbc51a9, 0x7d08f24d, 0xdfe5cc10, 0x3ccd7fa3, + 0x7b1666f7, 0x88b3d29f, 0xcf5b5a8f, 0x2faadc21, 0xd35fbb79, 0xf2c727ef, + 0xd7baf557, 0xac2ed10a, 0xa54c3aca, 0xb7a0ff3e, 0x7d057b57, 0x8be5149e, + 0xa7985f48, 0xc93b727a, 0x0d07f54d, 0x0ace6f24, 0xc79c67ae, 0xd6307a8c, + 0xb4772a5f, 0xdefdc2cf, 0x9e2a1ff2, 0x5ed89626, 0xde7850ac, 0x2fada3f3, + 0xc19cf1bb, 0xe26bbdc0, 0x0e1bf03c, 0x3bbdffce, 0x97c4e101, 0xfe50da0d, + 0xc78d57e2, 0x74296f22, 0x7dc0808f, 0x1719aeef, 0xd2e7887d, 0x7e532677, + 0x375dd3e7, 0xc021f9dc, 0x72e3bbdd, 0x4de943b2, 0xfe9fe201, 0xf70fbb0c, + 0xa97e20df, 0xebee8050, 0xe3765fdb, 0x3f27e4fe, 0xda2270ba, 0x9c050fb7, + 0x5e667f27, 0xe7b97887, 0x865e9f99, 0x2561d5ed, 0xef6cf50d, 0x15fe1fce, + 0x8ed570f5, 0x9a9f8a7a, 0x0d4bf47e, 0xe14d39f7, 0x677cfe56, 0x7dfb07b2, + 0x65d37db2, 0xf6a6ef88, 0xb93f6a26, 0x07ea95bd, 0x4be9f99e, 0x33f68dff, + 0xbf61f6e0, 0x4fdb3f93, 0xaa09a974, 0x04f0defc, 0xeee8fd7c, 0xa19f5cfd, + 0xb07287bf, 0xc919eb90, 0x3f7f92d7, 0x8bd6e679, 0xc6bbfaf4, 0x60a5181c, + 0x1f5661ff, 0x7d07d79e, 0x15fbfa4e, 0xc4ed533b, 0xce9cadf7, 0xaf74d5e6, + 0xd73e7943, 0xdc61883b, 0x72febaf7, 0x91477d07, 0x4afb10e1, 0x293f1176, + 0xbcc3ed0a, 0x6d05e972, 0x217dba4d, 0x9457bf49, 0x1756a3d9, 0x8b379f45, + 0xb8939b79, 0xf514f93d, 0xd539c430, 0xac1efc65, 0x5f6c7f4f, 0xd6b5fe48, + 0xd76bf743, 0x34be7114, 0x9a3d393b, 0xb7e57e45, 0x39630ee0, 0xcf02e41e, + 0x8eeb40d5, 0xfadf292f, 0x1a6fd913, 0xbed357c2, 0x784752da, 0x0e7f11f9, + 0x8ee7c658, 0x354b06a2, 0x1b592f3c, 0xe91c5e3f, 0x3dfd3274, 0x663a2376, + 0xde92f28f, 0xe8c6fab1, 0x5511d2fc, 0x27dc26c1, 0x906d6ab8, 0xe17ea9ee, + 0x5ee937e3, 0x2ac667e3, 0x30df8893, 0x2f76847f, 0x6a79a4e4, 0x70078f31, + 0x7114ef9e, 0x17a987a3, 0x32aff1eb, 0x75fb49d5, 0x6a97a4fd, 0xdc5d859b, + 0x5b19e221, 0x6bde367f, 0x2f39ef0a, 0xc09bedd6, 0xd5274e7b, 0x8fe7b3fb, + 0x5a143b47, 0xabc87648, 0xa527bc11, 0x09a161fe, 0xa1e2e8b7, 0xf51738d8, + 0xca77e61b, 0xe77ea59d, 0xe3296894, 0xdd3c58df, 0x3877da25, 0xea277efd, + 0x16e79dc7, 0x7a09d687, 0x2cf4aa3f, 0xed0e3e47, 0x2f907bb3, 0x29eb2eeb, + 0x3bb1ebd4, 0x0b4e9e04, 0x41dfc13e, 0x64cdb8a0, 0xb5df110a, 0xa4dad05d, + 0xe77bb60c, 0x44757f09, 0xba41e2a7, 0xc73ad88c, 0x9bf03f40, 0x7f686bd6, + 0xe4252ac6, 0x7eae76cf, 0x11e61c6d, 0xaf586e81, 0x495d98eb, 0x833b03f8, + 0xe75d6cfe, 0x73840eec, 0x3eb5fa64, 0x3f0797dc, 0xe77d1664, 0xa0a6c351, + 0xda3a3efc, 0xad246fbf, 0x1e786143, 0x384b51f3, 0xa3f7ed0b, 0x787d0ae3, + 0x582ea63e, 0x0af24359, 0x2f7d2d7e, 0xfe40dc15, 0x26f79d6b, 0xc6a7ed1f, + 0x853ef9ca, 0x1be054fc, 0xab8b1dfa, 0x7c2cbbf1, 0x7920ec3f, 0x2dccebaf, + 0x9eaef845, 0x9e60f3e9, 0x8fc494ed, 0xf4dd2d2c, 0xf7a7183b, 0x27485958, + 0x03eeaf97, 0xf80266bf, 0xafc17b35, 0x3fdf8099, 0x1571d9fa, 0x0d7a71c6, + 0x5deab779, 0xcdef74b9, 0x7f8ed129, 0x2d7ddd5e, 0xe21195b5, 0xcfe11acb, + 0xc5fd5ba6, 0x26e8ebb7, 0xfa5894fd, 0xf6e4ee3f, 0xe727bce8, 0x00463d12, + 0x239f103d, 0xa26e9ab6, 0x863485f5, 0x8aaabbeb, 0xbe01ea45, 0x229ab6ab, + 0xfa884f97, 0x3de3b131, 0x4f7114e9, 0xf518a05a, 0xa702f95b, 0xca87af4f, + 0xbb26fc93, 0x2c628fce, 0x92e31930, 0x845d338f, 0xaf4e1df7, 0x7e0c87f4, + 0xd3b8e0cf, 0xe1f8c3ee, 0x04d0969a, 0xaf0e87dc, 0xf2885a4f, 0x49d47a08, + 0x781eebfb, 0xb6d6e31f, 0xb8f3b64b, 0xf9d689b5, 0xc247a77d, 0xe301b937, + 0x5ac0fcdc, 0xbe5c7f6e, 0xe5d6fb78, 0x2ee7e94e, 0xbef3c62e, 0x3e9d7375, + 0xff36af8c, 0xe38a5942, 0x746c85d7, 0x705d6e39, 0xf2579bed, 0x5fdf8038, + 0xbaa2fc23, 0x347d1bf4, 0x7a7e20ff, 0x4e8ddb8f, 0x4ebaaf4e, 0x1c642f6e, + 0x5e217a8b, 0x29ca5ede, 0x6b8c63ea, 0x39497f24, 0x3c79573d, 0xfc90096d, + 0x2375869c, 0xe1f00e3f, 0x630f9c0b, 0xff8934e3, 0x8bc2f8d8, 0xef7506c2, + 0x8f7d0776, 0xe69af52f, 0x3d451c0c, 0x6476d754, 0xd0abb123, 0xdc2f7543, + 0x3f94385f, 0x78f95365, 0x3d2b9036, 0x1359e0df, 0x432a44d7, 0xc0df3a4e, + 0xc6df5fb8, 0x1d8e8fef, 0x4f42b7ef, 0xbf4a7c49, 0xcf82f319, 0xc29ff943, + 0xfa227d7e, 0xcf29d5fd, 0xfc0d8457, 0xdf0535e7, 0x44f17dc3, 0xf7be56fa, + 0x7226f34d, 0x63efa97c, 0x99f325e9, 0x45d98eb8, 0xecb5fb89, 0x0c48f117, + 0x3e0b14ff, 0x80e7037e, 0x07724f75, 0xbea0b917, 0xd3f99928, 0x7e8bdf00, + 0x29f7e569, 0xc42fed8c, 0x655aaa78, 0x5797cc21, 0xf584b4ef, 0xa1f736e7, + 0xf5ef040f, 0x33216cb9, 0x3bb95df0, 0x0671c1e8, 0xcbbd87ee, 0xc1e1e74e, + 0x7282994d, 0x481ed23b, 0xf7e06575, 0x4f743d89, 0x1e0e63ec, 0x311ff44f, + 0xc5cbcf87, 0xe87bbe7b, 0xacce84f7, 0xea7ca7cd, 0x61fc2f3b, 0xede01fcf, + 0x1a3e7b53, 0xd493cfad, 0x55364cd9, 0xad3c6f97, 0x2b67dfc4, 0x167d7176, + 0xf3f65bcd, 0x438be5bc, 0x63eb41e7, 0xf3d1fbf2, 0xfdf9b1b3, 0x6fa878e8, + 0xfbf263eb, 0x6f5c5d07, 0xf9e7df47, 0xf14c77fd, 0xc7bd6fbf, 0x8bafdc65, + 0xc5cfbf6d, 0x8f23abf9, 0xe3ff45cb, 0xe4fd184a, 0x115d6be5, 0x396b8fbc, + 0x63bf463c, 0x311427b9, 0xf9ae51b9, 0xcdfc323e, 0xbe5f81b5, 0xe807d844, + 0xbe474ea7, 0xff68790c, 0xd0f42831, 0xff57ce92, 0x72f4f18c, 0xc3a6d995, + 0xbe6d4b38, 0x13fbf843, 0xba673a1f, 0x7e56ed51, 0x744c86e7, 0x6a2d86e6, + 0xf455bca0, 0xf374f57c, 0xfabe72df, 0x57302bb0, 0x7fd21bf2, 0x5f5cedd1, + 0x9756fec8, 0xe467373c, 0xd01377b7, 0x665dc739, 0x3ababe46, 0xc698b029, + 0x4194fdbd, 0x7a569caf, 0xf201fe9e, 0x7bfe6ae3, 0xd7efb147, 0x8afaf98a, + 0xc53ee9bb, 0xc97fd5be, 0xebaebf26, 0xff51b7d5, 0x817bcad5, 0x7b862c3b, + 0xfc932b81, 0xf7efc4d5, 0xfba14f4d, 0x73c186ce, 0x1ab82782, 0xf6fe41e1, + 0xdbf9eba7, 0x2ce78c9b, 0xba01b5ea, 0x921ef7d0, 0xcb946c2e, 0x23ae8f48, + 0x36a58f44, 0x701bdd3f, 0xf0403f9b, 0x4c8e4a2d, 0x5ff018f1, 0xf7dd37f4, + 0xf6e42958, 0xfdfe2d1d, 0x3e09f7e2, 0x8dfb283c, 0x4efafce0, 0x1e7aab36, + 0xff234ccb, 0x2ce42c3e, 0x71cbde2c, 0xbc421ffb, 0x18795e80, 0x8e7400f1, + 0xcaf5e8a4, 0xe7ba7ee4, 0x374a6fa2, 0xae7d1f7d, 0x80ac66f8, 0x8e784bd6, + 0xd1385e73, 0xf0b56f7a, 0xb5df0075, 0x47af48b9, 0x87bfebc6, 0x5b80b9ff, + 0x493be5ca, 0x142cbc46, 0xe091fbeb, 0x87974a93, 0xfd7c1be7, 0x3bce38d9, + 0xb8f1f1a9, 0x768f8a28, 0x7fb583c2, 0x6fd01a71, 0x6d35d83e, 0x12a7e122, + 0x938a0f9f, 0x49ff228a, 0x5c6b6dfb, 0x0bc5ed0c, 0xfdc9be72, 0x963f8f3c, + 0x885a0bcf, 0x57d96eff, 0xc2bd6de0, 0x3145e77f, 0x2b6844c3, 0xdf2f32c7, + 0x7fce980f, 0x203ecaaf, 0x195c8797, 0xcec4fc51, 0xc09b0c7b, 0xc4bb779e, + 0xe63e40f7, 0x1f16f7c3, 0x8b75ccfd, 0xf43df0d7, 0xef4e385b, 0x1fc8479d, + 0x0a45a63b, 0xda719c5b, 0xc7b6c8b5, 0x6b3b6894, 0xadc17ee0, 0xbbe99acf, + 0x9ea66398, 0x2d7f7047, 0xfc99a6f4, 0x3dde3fa8, 0xfa2bbe83, 0xffa30ef4, + 0x45d0527a, 0x20309f7e, 0x830b783f, 0xc5eff079, 0xcb9ce6dc, 0x3ee629e5, + 0x14164af6, 0xfb13fbbf, 0xe103427d, 0x893df079, 0xe73c87eb, 0x7ce6e995, + 0xf38269f3, 0xebfb8a19, 0x3ee327da, 0xc4bed45d, 0xf1f1d3ee, 0x474e6edc, + 0xf6fea769, 0x304aaef9, 0xe77175df, 0xba7cf393, 0xb3bafe3c, 0xd58edcdc, + 0x461becc7, 0xb3e795c7, 0xa49fa85a, 0x2cd9fd77, 0xd2eb2e7a, 0x37be8a8f, + 0xfd8bc68a, 0x13e6472e, 0xa7beff25, 0x9efd1b30, 0xf224db11, 0x78099e86, + 0x687bd0bf, 0x06df412f, 0xf52f60af, 0xfe4b8800, 0x9aa17879, 0xd8efe517, + 0x9d5f0075, 0xd51effd4, 0x4fb8b704, 0x217642ef, 0xf821177d, 0xe59df179, + 0xf25aee74, 0x854f546f, 0x71adbc78, 0xa7319e3f, 0x18b3ff41, 0x13a4b0fb, + 0xb204c1ec, 0xfc0e74cb, 0x12378bf8, 0x5f32571f, 0x17d1e926, 0xe93f74ad, + 0x120bb5d7, 0x4b421b9e, 0x8adefc2c, 0x6bc7ba74, 0x86ff988e, 0x981fee2e, + 0xfbfe7e6c, 0xf5e67e55, 0x03dff264, 0xca05fb21, 0xa5fa855d, 0x00cc8eb2, + 0x3162e9f5, 0xf00fbe0a, 0xb64a2a5f, 0xf2859834, 0xb7ffef26, 0x961670b3, + 0xbcf9174d, 0x04ae5e58, 0xa7070e54, 0x30d62cf3, 0x6c9bfb0a, 0xff9c663d, + 0x58da7991, 0x4fa01fbc, 0xdf89f249, 0x74fba3fb, 0xf3f303ad, 0x9dd64bba, + 0x0eefc32e, 0x7dc5bbd4, 0xa366360f, 0x4673ebdf, 0x057da13e, 0x616cda51, + 0x0701ddfa, 0xcdba448b, 0x8c00fbf8, 0x614f9bbe, 0x3dfc112d, 0xff17be8c, + 0x1e1c518b, 0x76fc0fbd, 0xef2194f7, 0xc7b6370b, 0x2a9e17dc, 0x7e634ae0, + 0xad221fba, 0x635f78c2, 0x42ad7386, 0x3016e13f, 0xc444cf3e, 0x0b61ff43, + 0x6f0bef63, 0xe1fc7051, 0x1b73e341, 0x5f7a463b, 0xbeb20489, 0x93de8b4c, + 0xdf8920b4, 0x22eff44b, 0x115b9c8e, 0x6f015728, 0xafd88bf3, 0xe8de50fc, + 0xe1177e09, 0x4370f1bf, 0x17d40d6d, 0xe3c6cebe, 0xc9c530f7, 0x185dea9e, + 0xefcadd7f, 0x3efe2d6b, 0xec361d67, 0xf0c78a3c, 0xc9b51707, 0x2b2ace78, + 0xb17d718c, 0xd48fb443, 0x7f18bda8, 0x3fdf1100, 0x95f74bcf, 0x74f38bd4, + 0x9a7987f8, 0xc333f3d6, 0x67d30768, 0x7ac46ff4, 0xee8cfdff, 0x19f79059, + 0x408ec76d, 0xbf4afa9f, 0x87da0325, 0xe23e64cf, 0x03bed149, 0xebcf9dff, + 0xdf889797, 0x5d47c08d, 0x2733ca9b, 0xc6fa9b13, 0x5cfcc1b0, 0x18bb35df, + 0x73f954f3, 0x297f13a7, 0xba0a2f82, 0x7c51ff14, 0x3f68c22f, 0x972bbeb5, + 0x1c17dfce, 0x719e51f6, 0xd4e1a981, 0x1bdf5c1e, 0x13effe3c, 0xc84cc6fb, + 0x7918d4f3, 0xafca24b9, 0xe72c5ed4, 0x7accfb97, 0x3ce046be, 0xfc44a0f0, + 0xc7bd12c4, 0x1662ece5, 0x6671c3fd, 0xbd25c744, 0xbdb45332, 0x3fdf0b72, + 0xf646aa9b, 0x225e1ca3, 0x4e5162ca, 0xe2330166, 0x7f73c4ab, 0x5177ce13, + 0xf21a68e0, 0xaf9b74fd, 0x9f46af19, 0xb86150bb, 0x4e9cc4af, 0xffb17ebe, + 0x3d8af52d, 0xfb67e799, 0xddbab3dc, 0xdf997dba, 0x30df85ba, 0xb98d8d96, + 0x24f7ff67, 0x3bffa517, 0xdb18dc91, 0x4066e463, 0x7d3f313f, 0x7dfb18b7, + 0xff3f3ce1, 0xc05e6a6e, 0x7e3e7cf8, 0xe71f97d7, 0x15d0ec77, 0x0b8e8ccb, + 0x78416472, 0x6ec77f62, 0x2ab7f48e, 0xa2d6fe8c, 0x8522fa7f, 0xa7b0c0ec, + 0xc1ccbf6b, 0xe25ce67c, 0xb12ebacb, 0x43fc0f3f, 0xfd89e3df, 0xe34efaf9, + 0xd77d7cfe, 0x74337b92, 0x9d75f3fb, 0xcf3fb55f, 0x5bbfeeed, 0xd30f74c2, + 0xd604afbf, 0x165e7982, 0x7107c2fb, 0x9462783f, 0x3cc5aeee, 0xe35073af, + 0x3107f4fb, 0x4bcba37f, 0xfcf070cc, 0x340b8ce8, 0xe5573e7a, 0x2129f2fb, + 0x0b92f927, 0x665defc4, 0x7e41d998, 0x1fe7847e, 0xeb3e22c2, 0xb40d7e16, + 0x47fca06f, 0xa465dc8c, 0x6547ca31, 0xf2963cdc, 0x8abb0b3a, 0x0d3e6327, + 0x7fe533f4, 0x7a5eddbb, 0x98b0617f, 0x395723f2, 0x8af3a46f, 0x6aad5df5, + 0x7adf4ea5, 0xf5f78d93, 0x9a5df9c4, 0xfa29e482, 0xe019a5df, 0x489e7a27, + 0xa7dfcb0f, 0x9bbe62ac, 0x7de2e597, 0x9d774001, 0x3194b79d, 0x53fb4f7e, + 0x5d2b9d0a, 0x76483ce5, 0x630ed578, 0xd45b943f, 0x6bafd57b, 0xcd537f74, + 0x467c41ae, 0x5de52d72, 0xa1b517de, 0x3ee0afd4, 0xe611df4f, 0x77fa436b, + 0xc05b8cc4, 0xe04f98ed, 0xa5e858b3, 0x3666f349, 0x24e53ee1, 0x565f9713, + 0x7fc91be9, 0xe7917377, 0xc7551d84, 0xfe50cad3, 0x63eb9f40, 0x067dfcb3, + 0xc4531fd4, 0x717ab1f8, 0x2e03f08a, 0x137d6153, 0x0a7d76a3, 0xa683f5e3, + 0xbddd332e, 0x3c9ce02f, 0x9fdc4720, 0xd24a7a90, 0xc6e5ef03, 0x92cb5df3, + 0x63c87e85, 0x184f4879, 0xc157f89f, 0x8d2a73cc, 0xbca1521f, 0xf407cc44, + 0x84df210e, 0x9dfa364c, 0x034a8d8f, 0xfa1b79e9, 0xa03e508d, 0xfd7f4904, + 0x46642abc, 0x1ac45ebc, 0x1726b86e, 0x03b758f5, 0xb07c05e9, 0x4d1fcf52, + 0x5bbd922c, 0xb509f031, 0xe8c4a6f7, 0x3d12a61d, 0xc238304c, 0xa5ad7669, + 0xc42bf47d, 0x6e53a273, 0xc9d51fb4, 0x3fb4618f, 0x87c01fea, 0xf52fddb1, + 0x93ea3309, 0x8f05f65c, 0xf43feed3, 0xfb0f8c1d, 0x8c5fc22c, 0xa1dd4ba1, + 0x641f8b93, 0xbe49fa51, 0x983598ba, 0xca1f00b3, 0xf75e792f, 0x2a5ba462, + 0xfc8c51fa, 0x892c69a7, 0xe64d8be4, 0x57c907f9, 0xa2255e92, 0x4fa484f6, + 0x7841cb0e, 0x53b4ed2f, 0xa462e9de, 0x58bdd013, 0x4aed2f8c, 0x6af4e4c4, + 0xb0174879, 0x7ec1e61b, 0x97aa665e, 0xe4c933e8, 0x614cfa27, 0xdba434be, + 0xd7ddf6cf, 0xe8eb7084, 0xe3192db0, 0x80e80545, 0x3ed8357c, 0xe463db18, + 0x94bbe259, 0x2c9fc979, 0x9c394665, 0x670d04e1, 0x8dcafba2, 0xa0b363f7, + 0x7b94f08a, 0x6f8fdd06, 0x41b1d232, 0xc8ae7845, 0x444bf632, 0xa7a41ccf, + 0x89690fb4, 0x6ae529e9, 0xa9d39db7, 0xfa84e81e, 0xd2afd266, 0x34813867, + 0x25ccade7, 0xc53bb0fb, 0xfaf584db, 0xc5f4851a, 0xcbdf6ee4, 0x106fcf58, + 0x337eb9ed, 0xafd683ee, 0xde53ede5, 0x7ac0cc0a, 0x5ede3ac1, 0xc9b04f7c, + 0xaddfe385, 0x2fd8bdd0, 0xcbc7727c, 0x47be1ed8, 0xcfca5fbc, 0xe06fd6e1, + 0xf9847fef, 0x3cf10bde, 0x7c0ccb44, 0x9739ae3e, 0xf0b00eff, 0xfc172e67, + 0xe3695bb2, 0xc83c20f7, 0xc8715dc7, 0xce28c496, 0x65cafee1, 0x6f979d62, + 0x3f4cebe5, 0x1785557e, 0x37b2a9f8, 0x2d95d740, 0x1109c164, 0x3372ef58, + 0xf1f9f204, 0x10bc1be4, 0x0d288f28, 0x500aa744, 0x72fbf49d, 0xc0b67cd3, + 0xc7ef9e78, 0x92fa79ef, 0xf329bc79, 0x35ffb8e5, 0xfb4f675b, 0x469e7992, + 0x654ccbf6, 0x09ef3f7c, 0x91a3f917, 0x7c8298c7, 0xfec0b88f, 0x57faf289, + 0xbd9037e4, 0xe64722ba, 0xa5d47bf3, 0x97f15f30, 0x178acd9f, 0xcc9e7f07, + 0x62c7e4ed, 0xaf3e4f1f, 0xbdfdf30a, 0xf4cbc8dd, 0x30e9ad7d, 0xe19853d5, + 0xb9ddab1e, 0xfe7aaebc, 0x28f35f7a, 0x06b35dfc, 0x36ca8435, 0xcc7da15b, + 0x679fe0eb, 0xffe14627, 0x2830d93f, 0x00800092, 0x00000000, 0x00088b1f, + 0x00000000, 0x7dedff00, 0x45947c09, 0xf37f78b2, 0x093215cd, 0x87213b93, + 0x98884013, 0x861c2184, 0x4109264b, 0xe8098414, 0x720d7282, 0xeb22dc85, + 0x97f75763, 0xd9110441, 0x73d6f8dd, 0x0160763d, 0x18896151, 0xc3824830, + 0x12a20882, 0x75040411, 0x0844ae22, 0xf1e20c49, 0xabaf2e1e, 0xbe667bba, + 0xfc38666f, 0xddbf7ffb, 0xdb2e23f7, 0xaaefafa9, 0xeaeaeaea, 0x084c8eaa, + 0x908238b9, 0xadc4b45b, 0x9680a1cf, 0xc8401bfe, 0xd5fa25dc, 0x3f02242b, + 0x213c6376, 0x33fe1277, 0x192d7aec, 0xf01dc844, 0x289085bb, 0x2afda4b3, + 0x9fdefe83, 0xd328bff4, 0xf3bfcf72, 0xc84d94a3, 0x3a558caf, 0xd50a1dd2, + 0x8459ece8, 0x9c9b359c, 0x7c84be9a, 0xcce2392e, 0x7d690903, 0x965cff76, + 0x64beceef, 0x47e696be, 0xb048d4d0, 0xefde62df, 0x13d2e27c, 0x977cdfda, + 0x918f0bee, 0xfd22ed0d, 0xa43a6a57, 0xae9a1a27, 0x232f7e57, 0x41e93d1e, + 0xf2ad7948, 0xe271257b, 0xe57acaf7, 0x91d99277, 0x845efd06, 0xf69f8a1f, + 0x5907cb67, 0xcfff6932, 0xe6147fbc, 0xb9346c57, 0x97129a65, 0xc193d5ae, + 0x1e7ce1eb, 0x4e157f34, 0xc8fba793, 0x64246f17, 0x6cc89752, 0xbb9095d2, + 0xe67e8ecc, 0xf99c4238, 0x146529e6, 0xe1e9cebf, 0x5c5025d6, 0x4c396536, + 0x6308fdb4, 0x8bce9b96, 0x4cc588d8, 0x79f12df1, 0x9f0c0d4a, 0x3c52471f, + 0x4832f8c3, 0xe699e006, 0x14d1f53b, 0x8448e3ee, 0x93881bf1, 0x88c23e00, + 0x4252112b, 0xbf1846ac, 0x42475e1f, 0x2179adff, 0x57ccaef1, 0x1f027de1, + 0xd36244cf, 0x47137f41, 0xa775f12b, 0xfbd22169, 0xfbf2bb4e, 0xcb1388af, + 0xc2ac9a4f, 0x24c9b12f, 0xe0aed7de, 0xca1cbb93, 0x9e041372, 0x3cf1ab47, + 0xc515fccc, 0x01309d2f, 0x54d24c7c, 0x58c9e3fd, 0xb30d6f0a, 0x1cf6c5ae, + 0xb852178f, 0xbac12eb3, 0x4b44c002, 0xfdb409d7, 0x926c404a, 0x3d22ae8f, + 0xab189d58, 0xe707e9ed, 0x93761991, 0xee389e0f, 0x1499a0d8, 0xcfe5d22e, + 0x06913c03, 0x29837ffa, 0xd210c53f, 0xb2f80994, 0x18262574, 0x52d47107, + 0xde92d3b8, 0xd814da35, 0x132b488f, 0xfdb4e313, 0xdb4bf8fd, 0x3e066911, + 0xb0cf20b8, 0x2a383267, 0x53f552f3, 0xc131b4e2, 0x5acf37fa, 0x91787809, + 0xa38e81e1, 0xadf943de, 0x2b5f7d73, 0x2a7210e5, 0x942468ce, 0xa67467de, + 0x1f5f52e5, 0xea2ee63e, 0x4a95ed86, 0xd0b6efae, 0xc764836f, 0x52cf3023, + 0xf8cf5b8d, 0xa13a6aa9, 0x6f3f96ed, 0xf748adb0, 0xf8d43fcd, 0x2d23f008, + 0xc93bffa2, 0x1d7ad2d0, 0xeaeb1752, 0x0bdefc74, 0xddca2ce8, 0x2b17451f, + 0x9185ef5d, 0xdd60278e, 0xe8b8c3b7, 0xa309697a, 0xaf8e86eb, 0x01932245, + 0x74e2549f, 0x7e02ca2d, 0x04eba3bc, 0x951297ca, 0x81d1c953, 0x351856fd, + 0x5e1fb764, 0x757d78db, 0x096655b9, 0x9989f7c7, 0x4dc7ff60, 0xdf30d5b6, + 0xae293d16, 0xe96c78a5, 0x9a48d3c2, 0xa01bfad2, 0xcf2840fc, 0x70e0edea, + 0xabe5868b, 0xbee517db, 0xdd9236ac, 0x545fac74, 0xf29bb213, 0x4369e597, + 0x4bb68b95, 0x147fd2a6, 0xa2dbed2f, 0x453e0156, 0xbce67dbd, 0xdd1c604f, + 0x802df64d, 0xcd35d98f, 0xfb5f877a, 0xe01f30ed, 0x579b1d13, 0x454b187b, + 0x45ccfb7f, 0xef1e209f, 0xbcdd20f2, 0xdb0160f0, 0xe1f6fdb1, 0x1fd21e4c, + 0x72c3ac0d, 0xc5cb0ebe, 0xae53ab7a, 0x04a64937, 0x63f9468d, 0x5aa0b941, + 0xc67a957f, 0x17ef844f, 0x4ebac4d3, 0xfb42d089, 0x64535953, 0x1fbec35a, + 0xa64248a5, 0x64b2c91b, 0x21a33f9a, 0x7175e501, 0x1997b3a4, 0x0cd23ce9, + 0x0ce489fb, 0x5f862f97, 0xe4b4bf8a, 0xd93e312b, 0xa9ed6fc7, 0xf6cf384d, + 0x81a63f55, 0x786f2ebc, 0xa875e507, 0x191f3979, 0x48f38516, 0xd6e0fb60, + 0xd9391b6a, 0x059787d3, 0x428f3666, 0x0f40acb9, 0x313664f2, 0x7ea7e81b, + 0xc3d3fba4, 0x57b95c28, 0x6f285c47, 0x93901a6c, 0x9c63c397, 0x7e2c435d, + 0x72612df2, 0xf0c96217, 0x688e49c1, 0xdc5c9c05, 0xb53e514d, 0xff22bbaa, + 0x147d45ba, 0x1ccee9f9, 0xf963dc05, 0xebf94510, 0x7015f26b, 0x536e67ef, + 0x35c1bf94, 0xc2770141, 0x9e3f202f, 0xca4e5d97, 0xbfae37a7, 0xde7f515b, + 0xbf4859be, 0x895ebe3a, 0x4994d6d3, 0xd05b30f1, 0x80686e9f, 0x670e52c7, + 0x68a3ded5, 0xb725b89f, 0xe1cfcb44, 0x69bb31fc, 0xf94258ee, 0x897d6fa3, + 0x67221fa2, 0xd28e30ca, 0xa18912ed, 0x46a73eac, 0x7bcc4fb9, 0x37170946, + 0x992cbe3c, 0xf407ea04, 0xdb4b4327, 0xac5d2129, 0xf5a8dfa0, 0x11519e84, + 0xdd0fc8b1, 0x57c63748, 0x79303e6a, 0x074861f1, 0xf4f5e83e, 0x3e3e01b0, + 0x19ebe2f0, 0xb9d5f109, 0x7b8e07b7, 0xee3a36de, 0x18fc40f4, 0x10fc9512, + 0x43f25166, 0x1f928678, 0x7e4aac22, 0xe4ab9ae8, 0xa3be3507, 0x20fe4a6c, + 0x105ffa1e, 0x568cc77c, 0xbca94df2, 0xefe00f72, 0x5f9e7872, 0x1fe90abf, + 0xf0a987a0, 0x1af01e3a, 0xff6bc3ee, 0x2625b6dd, 0x61df660b, 0xe478041c, + 0x197620f8, 0x046c52e5, 0x3e561dea, 0xcca7a14e, 0x107ae288, 0xd69fa76f, + 0xf7d613bd, 0xa049c932, 0x967fd09e, 0xdcd3bae4, 0xc639df14, 0xd520a02a, + 0xa2b3ec6f, 0xd32c1ca8, 0xdf21b3bb, 0xefc1ef4f, 0x417bd2ad, 0xa7411ef5, + 0x7281c439, 0xa61f0025, 0x2f50f427, 0x3f40ff80, 0xff8411ed, 0xed077ea8, + 0x5179f256, 0x7234b93a, 0x06a4be20, 0x0d911dc9, 0x72106cd3, 0x3fb171d6, + 0x157ca366, 0x4a0da2f8, 0xe84772fe, 0x817da28f, 0x448f211f, 0x255206bb, + 0xab7f0227, 0x50c913e4, 0xa9371de2, 0x223ff841, 0x35e80bd8, 0x416f9bc4, + 0x0899037e, 0xbc4de94a, 0xd30f723f, 0x06a48d4b, 0xb242b2e9, 0x7f69972e, + 0x4be975f2, 0x7f4ba508, 0x64ffd533, 0xa69b42d8, 0xd18d77c0, 0x773ec329, + 0xfe60b91d, 0x3f5a06ea, 0xc5f95d61, 0xbff2d098, 0x5b8d8dfc, 0x281f549d, + 0x2464f4d9, 0x5afaf4a1, 0xa56f135b, 0x2ed6cbf5, 0xb4d1b48d, 0x7d44eb45, + 0x3c976bea, 0x7f6415da, 0xed8a3f7e, 0x264274df, 0x7c153f90, 0x795fa72a, + 0xd7ac1c6c, 0xccead6ef, 0xb9522d32, 0xd036e0de, 0x375151f5, 0x46c92c7f, + 0x8fc199b8, 0x54f8037c, 0x5e4a1b9f, 0x82de327a, 0x5933a3fb, 0x3ba90893, + 0x62b4d099, 0x81463fcd, 0x3a49567e, 0xd4b8c196, 0x1fffa0f5, 0x595afee8, + 0x77d4cf2b, 0xe11e720d, 0xb5d05aeb, 0x6fb1eeb2, 0xcdf848e4, 0x557e07a3, + 0xbd062f97, 0x3b67ea8e, 0x89bb3c84, 0x45eb04dc, 0xe2b883e0, 0xdf93ef50, + 0x99bb2178, 0xf66badc2, 0x787e4a47, 0xc421e422, 0xaced674f, 0x0969bcbf, + 0xaa36874d, 0xfe5e90d7, 0xcf585cf5, 0x9ee12f52, 0x5a581a4a, 0x0e4773a6, + 0xb654aca5, 0x687a874a, 0xaebfc6d9, 0x33c533fb, 0x5eb06639, 0xdd2fdb4f, + 0x43c7f6f8, 0xa6bfbe40, 0xa6cb1d8b, 0x7de29261, 0xffa4a974, 0xe8f8e516, + 0xdbfaf250, 0xfb164b7a, 0x8fb460fe, 0xedafa51e, 0x40ac93d4, 0xeed4147c, + 0x414c7bd4, 0x3cdb52e8, 0x1e02648a, 0xdd03d27e, 0x9121debf, 0xf820f484, + 0xa476f55c, 0xe909e383, 0xa5e4e9c8, 0x5cfabd5b, 0x412bf4c9, 0x2bbe7527, + 0x0afa8cca, 0xca7a87b4, 0xf6ff1b1b, 0xf14fc526, 0xcc2b0627, 0xf76ff8bf, + 0x4e3cc245, 0x5f18ab69, 0xde34b0bf, 0xd62dfb46, 0x98cde339, 0x2fc5efb2, + 0x6df91afe, 0x8ebf87de, 0xd93fa827, 0x38b93492, 0xdf9824cf, 0xc4efe79c, + 0x0e25cdf9, 0x17e2bbe4, 0x9fe83b64, 0xf464b5e7, 0x45d6416b, 0x175b3441, + 0x15d356a7, 0x4a77e74d, 0xf38044cf, 0x8b5aeca0, 0x517bd287, 0x28dafc18, + 0x8402ffd6, 0x9d191bcf, 0xf86b45ba, 0xdf4ba2ba, 0x3cd75f9f, 0x39f404d2, + 0x004b6a9d, 0x6892af3d, 0xd21f1c9d, 0xfcaeda45, 0xa3026161, 0x8568b10f, + 0xa8f2a47c, 0xf943be00, 0x2c2d9d26, 0x5c8f515b, 0xbff5f74c, 0xc74ff790, + 0xd0f405dd, 0xf5c1f153, 0xa668caf2, 0x269fd327, 0x7e5fc7e2, 0xf7ad9beb, + 0xf5b28f35, 0xabbbd62d, 0x7fe43468, 0x1fad887b, 0x839c97a8, 0x602772e3, + 0x243bcefe, 0xe2060794, 0xd7aeb60e, 0x56baf8e8, 0xa13e0be6, 0xb9c2d6e3, + 0x842fcbc7, 0xf14e6f9d, 0x27dcc8f3, 0x7dbf3d68, 0x8bfa12be, 0xac4f6c0c, + 0xfd7c79db, 0xf7cd1cdf, 0xc9febe5d, 0xcf4171f3, 0x5b73eabf, 0xeeb5ce99, + 0xe95eb0cf, 0x605a74fa, 0x30eceabd, 0x761b33ef, 0x5d377c7d, 0xc56a6727, + 0x4fca553a, 0xde2d3af5, 0xa7f236fc, 0xa99e9d7a, 0xe83e3b7d, 0xeded7d3a, + 0xb0664f78, 0x2bbffa75, 0xe6fe053f, 0xa7e52b46, 0xf0a18790, 0x728796a8, + 0xa9f105b4, 0xe7f48796, 0xc8141910, 0x04ef827f, 0x5abc95bf, 0x1dc81d7e, + 0xbe0a5f2f, 0xe0a5f2f3, 0x957cf53b, 0x5be753f8, 0xf9472ce1, 0xf0edbec4, + 0xcf4a64a8, 0x6ac906b2, 0x3dbd60b0, 0xd93c5300, 0x35231b70, 0xfd63927b, + 0xae0a9761, 0xa9b79555, 0xbcaabb60, 0xa9570543, 0x5c70bbca, 0xf4bbf565, + 0x5b81e504, 0x10f75e51, 0x3d804671, 0xad7651a1, 0xa76ca8a6, 0xeb465e63, + 0x47486fb7, 0x12697b7d, 0xc474dbb3, 0xfc8197e9, 0x4477376a, 0x75fc5346, + 0xb373f184, 0xca3223bd, 0xdcd32ecf, 0xf5fca320, 0xdae8c8b8, 0xaa1af620, + 0x3cfd2249, 0x62fe5424, 0x4d90bf66, 0xef408b69, 0xa0ad91af, 0x3c5ecd0b, + 0xcef41229, 0xe31e86f6, 0x73efd327, 0x43baa1f6, 0x903db9da, 0x49b4039e, + 0x38b3fe94, 0xe710b63f, 0x7ce8c353, 0xa2943566, 0xa57b3e3e, 0x4d735e92, + 0x9ccf510b, 0x1efd04fb, 0xe12fdf44, 0xaf3f14ed, 0x2b212fcc, 0x1d289f91, + 0x297760f5, 0x77cca359, 0x2ecffb70, 0x48fde7c1, 0x87b9c53f, 0x3942d5cb, + 0xb064fc73, 0x0995ec57, 0x836749f0, 0xdcef788c, 0x9e08b920, 0xa83d986b, + 0x3ca07482, 0x8569f813, 0x2d0fa0f5, 0x7cb75a6f, 0x5a01e83a, 0xf1eb6ca4, + 0xda68e7ec, 0xaf58f5ba, 0x71bf00ed, 0x0938ed24, 0x08ed3fb2, 0x64dda1b3, + 0x00cb8447, 0x3f7c6ff4, 0xa3b401ed, 0xce30ac18, 0x67df1df6, 0x3fb4df03, + 0x79062864, 0xecca9ed5, 0xbf1a4b23, 0xe57266cf, 0x5b57a461, 0x37e99eb4, + 0x99fdff0d, 0x06fae704, 0xf7d82b3a, 0xf9e38477, 0x30cdf2ad, 0xbff6c117, + 0xfd30e41f, 0xd0a9f372, 0x61f20713, 0x19bc9904, 0x704517c6, 0x07db953e, + 0xed3175ff, 0xa76ebcbf, 0x2fcd167e, 0x6ca7eb78, 0x37db0fd8, 0x4da67d33, + 0x5dd2b847, 0xad1e68f2, 0x61c616d7, 0x056eefe7, 0x160db77d, 0x9e423747, + 0xab70d98e, 0x4f0c14d3, 0x5e21a53f, 0xd13f10ae, 0xfbe47a31, 0x48fc7d7f, + 0x2bf28236, 0x609465c2, 0x767e3fde, 0x0ec1e41c, 0x98a9f203, 0xc5da99ef, + 0x6e5c7fa8, 0xfe62fdde, 0x4ae2f85d, 0xafb92de7, 0x7ff6de64, 0xe21f7a71, + 0x5d7aa8fb, 0xe379f204, 0x8c6f08fd, 0xaf78e2b0, 0xfeabdf90, 0x337dd1af, + 0xe5e47ba5, 0x7fc7fde7, 0xa68779f1, 0x9ce9befb, 0xc3b066ee, 0x13f5be55, + 0xe56aef8e, 0x537fa6dc, 0xba7a17be, 0x3890befa, 0xf0a5a225, 0x744f0e70, + 0xd2e79e4a, 0xc388f77d, 0xd2113a79, 0xdd475048, 0xcad38f27, 0x2a4b24c3, + 0xde132828, 0x7a071dec, 0x8aa932cb, 0x4737eca8, 0x6476d3b7, 0x940c474d, + 0x2d0e242b, 0x217217bb, 0x3c91df1e, 0x15f9d768, 0xb4852db1, 0x9a8ed482, + 0x3bdd6902, 0x97b42547, 0x923f2184, 0x9e3df57a, 0x0d11f516, 0x1de8019d, + 0xce2b00a5, 0xbe9f5a77, 0x8bc20722, 0xa293d8e9, 0x313f7f2f, 0xcfccd63a, + 0x58bd1d7d, 0xc46fd33e, 0xfbe8727d, 0x66f8e55c, 0x4ba76699, 0xf36f41dd, + 0x8c15c71b, 0x291e0093, 0x3ca6de9e, 0x7bfaa463, 0xd1d1dc12, 0x618fecf1, + 0x72ef2df4, 0x141b63e2, 0xe694d01b, 0xa9563f7f, 0xec193627, 0xae0d5b24, + 0xad4fd0b5, 0x1b4ddef2, 0xa1dbcecb, 0xef13d0f1, 0x421e0453, 0x3efaabf1, + 0x1be80665, 0x667c6103, 0x74c6f8c5, 0x29631bb1, 0xf3d47a9c, 0xd5f1a495, + 0xd75b942f, 0x60fa073d, 0x2b7fd33d, 0xf57bb386, 0xda326d8a, 0x0c1ada0f, + 0xb18e892e, 0xde177eb8, 0x1b56b4c7, 0x9eb7dc09, 0xab48eba6, 0x55fe04bd, + 0x371c0df3, 0xcd67075b, 0xea86a746, 0xee5896d5, 0xb24d908f, 0x3fd31e61, + 0xcd31173c, 0x9ede7682, 0x5e76feb1, 0xab37fdef, 0xedcf9017, 0xedef54c0, + 0xcce2f20a, 0x65ef04fd, 0x6d23b689, 0x1cbf9642, 0x23a3ce50, 0xa9e3d186, + 0xb4167b68, 0xf294dcd7, 0x2857b414, 0x06e9ec37, 0xcec859f8, 0xc40c2359, + 0x64e94619, 0x56b5ef90, 0xde95c9f9, 0x9cf196bf, 0xfbc2e9fd, 0xfa6567a2, + 0x692dedda, 0x741eecec, 0xa5bf67f3, 0x988ef4ed, 0xd3daf78a, 0x93bcec0c, + 0xbbb87f7e, 0x6f5f5d07, 0xf81189e9, 0xeabdd74b, 0x4e70ade0, 0xabad928a, + 0x32b17f69, 0x217c0919, 0xce1b1bc6, 0xe7be23e6, 0x0246b0bd, 0x8fbe22f9, + 0x7fd1d258, 0xb1f54d01, 0xf8c53f8c, 0xf4741446, 0xf0f932af, 0xe7e466de, + 0xd716b319, 0xb4c3b093, 0xec0979c1, 0xeb0e7024, 0x3db7c84b, 0x5e1f786d, + 0x20ec4611, 0xdb35bef7, 0x7ce146ba, 0xb66f782c, 0xb7acacd0, 0x04fcd3f0, + 0xa0571f28, 0xe91787bc, 0xc76658ac, 0x4341fb29, 0xe2767e9c, 0x0f5bad32, + 0x1fb281f6, 0x77e9c4f4, 0x9d05fc0f, 0x5cefd3b7, 0x4f4b4f7e, 0x22cc27b4, + 0xcc27b456, 0x9c4e1e5a, 0x3aa2e77e, 0xbd350e3e, 0x56fa71cf, 0x96896944, + 0x2242abce, 0xdb954bf6, 0x9f764ffe, 0x23ff1eaf, 0x70e36eb0, 0x779fb87e, + 0xab5c1a34, 0x9dcb03d3, 0xb8f6618b, 0x3dc51bf4, 0xc5cf07bf, 0x25e5b70b, + 0x8aed2090, 0x1b07e2b4, 0xa5e1f971, 0x7983d682, 0x9230fc56, 0x6f07fab8, + 0x66f982cf, 0x81cede05, 0x5fe81a7c, 0x4df1163f, 0xb091c44f, 0x97a95e7e, + 0xf13d8347, 0xd19abd95, 0x678c83ab, 0x9f679f03, 0xf5f22d38, 0x5b626e8d, + 0xa29e8415, 0xdb347c5c, 0x459f0117, 0xa8788159, 0x074cf7cb, 0x2469b87e, + 0xefeb05b1, 0xc42f9c2f, 0x19a2ebb8, 0x18762b7e, 0xdb405ed0, 0x011455ed, + 0x71733ddf, 0x74959b3d, 0x8d863cfb, 0x4f36eea3, 0x76d3f41a, 0x083ff72b, + 0xe173df41, 0xe018f68e, 0x30b449c3, 0xda4187e5, 0xb7ecc92a, 0xbe94ae3e, + 0xd6ac3f15, 0x102bd3f9, 0xae74ebef, 0xc576befe, 0x22f3643d, 0xe6def519, + 0x95fefc83, 0x62eee3db, 0x499a4cac, 0x97b02ed5, 0x68495734, 0x41dbbbc7, + 0xdeba22c8, 0x14b87aef, 0x97d34ded, 0x8234bebe, 0xca907f7f, 0x0912bb8d, + 0x77a699b9, 0x09da56cf, 0xb70596a6, 0x3f7839a7, 0xfa0748d3, 0xa85f4cf9, + 0xfb702fb2, 0xe541e383, 0x17e02ff7, 0xc60fd72a, 0x0e43bb72, 0xbd7901c9, + 0x3d39e960, 0xf8a109a8, 0xc3ca85ba, 0x8b905a9e, 0xab5b4c46, 0x157e98cd, + 0xf604fb6b, 0x8eb1f3a5, 0xb6ee414f, 0x52e4c87f, 0x4c73cae7, 0x418f2f9e, + 0x2ef2c73b, 0xd78dff6c, 0xd3ea3b58, 0x3e3efe41, 0x8fc51c71, 0xeb5a2fe1, + 0x9b878a12, 0xc0d3353c, 0x35e84525, 0x905aac8f, 0x127e8b11, 0xefc041d6, + 0x32deafb1, 0x7133ec1a, 0x00db86af, 0x5cf22b7f, 0x62b18f78, 0xe7f41771, + 0x0fcdd232, 0x0d8f7ae4, 0x3fb81a79, 0xb16ea1bd, 0xd76d1ba6, 0x0dd3b0dc, + 0x35cb0efe, 0x6b3da0df, 0xf984cdf9, 0x287ef17f, 0x6919fb3e, 0x4c13f13b, + 0x171d2f78, 0x50d44aee, 0xbd46ee38, 0x17ea0975, 0xe0a95f4c, 0x2c976834, + 0x7e0a1c7f, 0x8264fb64, 0x16b13e7e, 0x087daf94, 0x0b92bfb3, 0x0f945f14, + 0x8fc40c60, 0x2dab5aef, 0x92fc9f68, 0xd0fb29db, 0xce8ea1f3, 0x4f8a2be7, + 0x6a1ecb80, 0xebe3051a, 0xabac48d8, 0xb7d89169, 0x912df292, 0xea337780, + 0x13aba7bb, 0x16e31531, 0x6bd947fb, 0x3f41a36b, 0x9999229e, 0x43d7095f, + 0x10121f05, 0x4c9e1456, 0x8bbf9c98, 0xa8539feb, 0xe3a30dd8, 0xd35887bd, + 0x46dddea0, 0xf8a1a912, 0x3b50529f, 0x5299f710, 0xe7ec145d, 0xe30542a0, + 0x8bfa5087, 0x72ea2758, 0x81af41a7, 0xc98db8f5, 0x11758a83, 0x6bbbb44e, + 0xecffb03a, 0x7b1ebe38, 0xd22e3f31, 0xfd60d893, 0xbde8ec54, 0xa062e80a, + 0xa5e303fc, 0x9b98ca72, 0xd19cfa83, 0x7f3fe748, 0x8a5b987b, 0xd9a7a3f4, + 0xfa034fd6, 0x1c9484fc, 0x4a3a97f4, 0xd80447e5, 0xb8693c71, 0xeb47419e, + 0x7d5cc306, 0x54ebdc1b, 0xfb30dc50, 0xee0ccbce, 0x2d6761c6, 0x7978d383, + 0x777066e2, 0xdbddff51, 0xc743fec0, 0x621fcbcb, 0x1f011f70, 0x45b3e566, + 0xce0c63f9, 0x1927f911, 0x7fb4483c, 0x1843c18a, 0xd3c9fc7c, 0x0f4139b7, + 0x8ffae289, 0xaee783d5, 0x6b7b378a, 0xde96fdfc, 0xf3726389, 0x772b1874, + 0x98cc9d3a, 0x08cbf400, 0x5e55fe5e, 0x02c5e85e, 0x493ea27f, 0x266f5e0c, + 0x80bf37af, 0x64e129eb, 0x5bf31879, 0xba524675, 0xbde86eee, 0xc617ca1a, + 0xd03a7345, 0xdaf80676, 0xed11f411, 0x244b7e89, 0xe9b497a6, 0xbbd89d98, + 0xfdb1c66f, 0x30f3f684, 0xd293d3f6, 0x909bda15, 0x81f80fd2, 0xf39681f2, + 0x80f81681, 0x7c6c5590, 0xc028ddb4, 0x3fa3b9b9, 0xbeedbff8, 0xfba7cb40, + 0xcbe6adc6, 0xcddf3807, 0x81cec25f, 0x703d511d, 0xce1118bf, 0x403244f4, + 0x380f8f39, 0x8b89de1e, 0xd2f4f362, 0x7ec24125, 0xa63c7096, 0xc84d7a78, + 0xff79faba, 0x97e78f9e, 0xbd1fb79e, 0xd7e4326c, 0xcd9ab0df, 0xd60bd187, + 0x85ea3447, 0x3bda2b8f, 0x3f5558bd, 0x98702e97, 0xac0f746f, 0x311848ff, + 0xdab277e2, 0x9b3d2f5b, 0xc7a0abe9, 0x27ca2f96, 0x74ff6127, 0x85f78cde, + 0x952a5c65, 0xe3d26f2f, 0x64ad6bfd, 0xef3cbf43, 0xe00ec73c, 0x79f334f3, + 0x5d3cd99a, 0x87257e0a, 0x88eed23a, 0x2f63e408, 0x65edbdfe, 0x14f6f0e6, + 0x7b582372, 0xd1422720, 0xd34bfdc5, 0x85538c45, 0x559e2f4f, 0x84f813e3, + 0x32f58df5, 0xc6297c95, 0xf5a87af9, 0xfb33fe9d, 0xcaf563cb, 0x08e9437f, + 0xc945a7fa, 0xe975e5d7, 0x7d327b9a, 0xae8036f5, 0xf3f3e717, 0xfdc71939, + 0x0a485286, 0x7cce0fec, 0xfec37562, 0xfb80d9b9, 0xfd92e7fe, 0x505c5c54, + 0xaefc20ff, 0x47b6173e, 0x1bec09e9, 0x7b40fb6a, 0x06c9b59c, 0x0967e5f7, + 0x550edffa, 0x6fc033d9, 0x57c9b373, 0x295fb7cf, 0x4cf111e1, 0xc3b40cbf, + 0xe68a7dd0, 0xb868300f, 0x018dd73c, 0x5c203d79, 0xf0d57705, 0xe0c8c4fd, + 0x293b0e04, 0x2034f14c, 0x3187e459, 0x3f513af8, 0x51bf958c, 0x5f70e794, + 0xa208fe55, 0xfdb28784, 0xb0a9e624, 0x20ff7031, 0x78d8a0f4, 0x2e43ce0b, + 0x4be010d0, 0x80d53803, 0xc196f5be, 0xa08d7a05, 0xce94a853, 0x3dd82ab3, + 0xf0bc6a7e, 0x977e6033, 0xbb40f2e8, 0x047615ca, 0x4761568f, 0x3a348f68, + 0xc768aee5, 0xadf605eb, 0xf747788c, 0x32bf5a78, 0x3a7a75bc, 0xff0a1f85, + 0x256cfd0c, 0x258fd31b, 0xa54c998b, 0x575a95e3, 0x23df41d8, 0x16a35625, + 0x4aedc4e9, 0xe94bf770, 0xcbc77db1, 0x6eb3240f, 0xc18e30ec, 0xee54ae5c, + 0xe3bbf1f8, 0x369fffb0, 0x7dfae159, 0xf7b3c370, 0xb838be81, 0x4c8fff61, + 0x5fa1304f, 0x60f718ac, 0xdfa29bf0, 0x380deb73, 0x370dc1fe, 0x43f281cc, + 0x01e86a3f, 0x84fc377c, 0x9988097b, 0x9237c6f6, 0xb91f281d, 0x25392c9f, + 0xd5c19c41, 0x7c5e45ea, 0x7e8f43fc, 0x231f141e, 0xcc2e3e19, 0xc5b4fc05, + 0x41e65c1d, 0x8b0a62a3, 0xe9f5e067, 0xb9fd03b9, 0x2b17493b, 0x23db5dd8, + 0x3b6a3b58, 0x3a22d1e4, 0x787dfa3f, 0x9f811d07, 0x07e23fde, 0x3e4c1523, + 0x29448f38, 0x926302e0, 0x39a17ca2, 0x4b7f915d, 0xfc8a0de2, 0x14fd2d5b, + 0xc18c98f0, 0x5bb7f28a, 0xf8f014f3, 0xe5155bdc, 0x0a456c8b, 0x56bb9fb8, + 0xdeffbe51, 0x21fe657a, 0x721d0322, 0x41775a8e, 0x1b4bf03a, 0xb507359a, + 0x7482ed54, 0x1d0cb7f0, 0x90ec3b6a, 0xc1776a1f, 0x15876177, 0xce30f0fa, + 0x3b2ec22f, 0xf4b93649, 0x89afedc1, 0x959e9a5a, 0x649f283c, 0xafed1d8d, + 0x078e61c9, 0x473d29e2, 0x2814aa91, 0xb0ec0237, 0x33850894, 0xfc01fece, + 0x32a73aad, 0x2051dc7b, 0xbbbbc80c, 0x788ed022, 0xf1b55754, 0xce43ea38, + 0xc3a39054, 0xe62b263b, 0x8707e23d, 0x6479de62, 0xf74e8abe, 0xf342e02a, + 0x6fe5146f, 0xc8ac5c49, 0xa8f2d5bf, 0x2b8f4e8a, 0xcfaddbe0, 0x4ab4e8aa, + 0x1597a745, 0x1bbf82f9, 0x076c7db8, 0x3a68b5d8, 0x0054d3cc, 0xa5b9b874, + 0xdb91e903, 0x74005354, 0x16b4721a, 0x6dc035e9, 0x3bf1002f, 0x2ed56f68, + 0x5cf4dd48, 0x4efef503, 0xee9035cf, 0xb023e7a6, 0xcea9ed8f, 0xb56f74c0, + 0x5bbfbf15, 0x7be98b9d, 0x3f4c36d5, 0x698d1ea8, 0xd31db553, 0x2c5aeada, + 0x9ebab9bf, 0xf862d7d9, 0x0bf1473e, 0x38368c76, 0x9cbca253, 0x0db2f28a, + 0x5f2850ce, 0x177066ef, 0x0c29930e, 0xebe5648e, 0xf2829a9f, 0x8cf83f74, + 0x30bf81c4, 0xd824cf4b, 0xdd3409ec, 0x8186e70b, 0x5a89b8be, 0xe4a7688d, + 0xb1eb9031, 0x525fbc31, 0x4296c632, 0x5ec5d2c8, 0xc18431f8, 0x2307eb28, + 0x1bc1f8b3, 0xe21b6b61, 0xc61edfab, 0x97c6f7f2, 0x4173818c, 0xf330fae9, + 0x29747e97, 0xc0528daf, 0xe649f595, 0x88e8fd2f, 0x7654c97e, 0xe5091492, + 0x36c3d09f, 0x20438e48, 0x1e8dca7f, 0x1aa627f4, 0x6c2bfa30, 0x8044b16c, + 0x85e0ea5d, 0xcf8011de, 0x672edc83, 0x3374fd23, 0xeda79a69, 0xff7d83a7, + 0x124f4aa8, 0xef2941e9, 0x56b76853, 0xf413bd63, 0x3a6de724, 0x413ffc02, + 0x51007662, 0xa604ddee, 0x6edfb4af, 0x21e0f3c0, 0xc60e6d8d, 0x9f024811, + 0x149f718b, 0x11c2f7f3, 0x7489df22, 0xf9128f6b, 0xe5538e1c, 0x1d60a927, + 0x5f19df2b, 0x05fe748d, 0x904ff9f1, 0xca7c6a0b, 0x97a66609, 0xa0a96db9, + 0x50f808c7, 0xe41cad91, 0xdb3ca1c7, 0x83ef30f5, 0x17930376, 0xf5d708f6, + 0x0db33768, 0xfecfd3bc, 0xc3a09d55, 0x1f00777a, 0xddc4fdc3, 0x3515ca32, + 0x604a5ffe, 0x15f22afa, 0x0aefbb9c, 0x21cd73c7, 0x1cde290d, 0x387b5e84, + 0x0974ce1d, 0x277df76e, 0xf9fbed81, 0x6e37cb13, 0x85cf7b81, 0xbb74d861, + 0x93ea37bd, 0xf31255ed, 0x3aa96903, 0x560df2cb, 0x33f4128e, 0xd1bf029f, + 0xf70d8dfc, 0xcb4c3f9d, 0xdc30b67f, 0xb9967b8a, 0x6eefe20f, 0x8c5a785e, + 0x69bff511, 0x61f35213, 0xfdc29e1f, 0x6847a79a, 0x59bdd1e3, 0xd337a51b, + 0xfa9b6676, 0x2418a32d, 0xf48b6373, 0x4e2e1451, 0xa41977b9, 0xd71f3d25, + 0x595dd5c3, 0x40cb6be6, 0x22a72f0d, 0x5bca2063, 0x74d5fbcf, 0xc916335c, + 0xe51e7616, 0xf4adb8fb, 0x045de2aa, 0xf1e21fbf, 0x78091447, 0xf1cbdede, + 0xe5edea2d, 0xe0482af8, 0x245922f7, 0xb8aca2eb, 0x0125b8f7, 0xbda63dee, + 0xbdc42bdf, 0xeb9f3288, 0x59eb1fbf, 0x75eba5bf, 0xb9104f2e, 0x9d812fbc, + 0x89e90f9b, 0x9d55ee0d, 0x277db377, 0x87b9f27b, 0x67f9d206, 0xe8359837, + 0x7ca33457, 0xb3a1d00b, 0x4751d39e, 0x4dfd61ea, 0xecfcce74, 0x96261230, + 0x5e1fc7f8, 0x36b67f6e, 0xf7fc0b99, 0x7b1e01e7, 0x9cfeff81, 0x005351db, + 0x8fd8b0fb, 0xbba83dc5, 0x03ef98ba, 0x77bf2855, 0x78422f57, 0xd313b54f, + 0xf9cbd5bd, 0xf983503e, 0xc33f55ef, 0xdf1701f7, 0xf7e3d607, 0x98c9ea86, + 0x6076a8ee, 0xbd8ba63a, 0x1df4e402, 0x47c60746, 0x81acfdbe, 0x675e7dc0, + 0x47e30183, 0xf1788ae8, 0x538858b9, 0x58579832, 0xd495e302, 0x1f978afb, + 0xb3fb7e54, 0x0b7ed8bb, 0x99e378fd, 0x2ebd3f40, 0x241d3f34, 0xdf390e5c, + 0xd0743945, 0x07d6e42c, 0x7808b60c, 0xa2ad833f, 0xf72807fc, 0xbe78da0e, + 0xed833f73, 0x601c9f3c, 0xefc043b0, 0x944ab831, 0x73dac03f, 0x063df80a, + 0x4df288d7, 0x7831760c, 0xa21fd3ed, 0xd223cc5c, 0x056f586e, 0x2091f4c6, + 0x79cd0b62, 0xdd9d61bb, 0x24733892, 0x826333ac, 0x56fcf905, 0x00dde2cb, + 0xa558c98f, 0xcdba1305, 0xa861efd4, 0xa45b1f97, 0x53237a85, 0xea187dee, + 0xb8f9ea8d, 0xe8debfd6, 0x061ed7cc, 0x9575ac78, 0x236bf416, 0xbe81c5c8, + 0xf22c0476, 0xe2213ec5, 0xd836faf0, 0xaeca3f71, 0x247ee3b7, 0x477f9cf0, + 0x9c3352d1, 0xb325ea03, 0x43b8e304, 0x404f06f2, 0x05c5630c, 0x1e291aba, + 0xe13c12ea, 0x2b3ce98b, 0xf0821e01, 0xd97f8b63, 0x109dd5fd, 0xc2383f64, + 0x2be807e5, 0x23ffb445, 0x3f835d74, 0x4bc70442, 0x88ccc365, 0x755e7899, + 0x189e8044, 0x0490f5c3, 0x2dfe6948, 0xbfcb1d3c, 0xef6c941f, 0x30f8bc82, + 0x03b79f81, 0x1861cde5, 0x73279507, 0xe40238d9, 0xcb9f328d, 0xdf62239b, + 0xb2e2c01a, 0x8b0d49cb, 0x7c4cbee7, 0xb8dc405f, 0x84a71e2a, 0xa5b1eed4, + 0x6f178b07, 0x2e2f1a0a, 0xfd031bfc, 0xb0b9f96d, 0x93cf930b, 0xc3d17641, + 0xb9686760, 0xab971dfb, 0xcca0f0a1, 0xe0e285ff, 0xf90e2389, 0xbc3c5423, + 0xf9c08be0, 0xb6f3b0d5, 0xea9fe196, 0x81c4c69f, 0x8823bf20, 0x6794ab1c, + 0xcf212f87, 0x97f1f2d4, 0x6693bb92, 0xfdc1a794, 0x98b91043, 0xcb54e30a, + 0xc93e6745, 0x7505fb80, 0x0a68f42a, 0xd3de213b, 0xed0c23b9, 0x8e31f514, + 0x0fd0448c, 0x83be3bf3, 0xeb122d78, 0x371c3c41, 0xf6846e39, 0xbff33d25, + 0x2dcdf110, 0x753f7d5e, 0x7923c62c, 0xfb0a7bf5, 0x9efdf7e9, 0xf20b1d49, + 0xdec9bbad, 0x1921da1f, 0xc85d1fcc, 0xbef1508f, 0x3ed91343, 0xff92981f, + 0x8e5838b7, 0xae7a369f, 0xf4e74dda, 0x62bf86ce, 0x57d9ccdc, 0x56c1c79a, + 0x265dba5c, 0xb68f8a46, 0x0dc4110d, 0xe52d1be7, 0xd4969a3f, 0x2b8c36c9, + 0x4d07bad2, 0x5bd7f08c, 0xe974ff98, 0xcadc08a6, 0x5c1b364b, 0x92fd6963, + 0xd1b327ad, 0x0ea1f5af, 0xbe730fbc, 0x22d75922, 0x13d93cfa, 0x1b594fc1, + 0x353e4edc, 0xad87e991, 0x8327c2db, 0xbf5a56bd, 0x25deed13, 0x707493b5, + 0x4dca2a0f, 0x3e21d44c, 0xa7b43968, 0xb8965f3b, 0xe41eeb1e, 0xfc2caf7f, + 0x665f5bb7, 0x7a92a976, 0xc60c2b9d, 0x36b5feb7, 0x3929c788, 0x4dfb406a, + 0xf46ffae5, 0x4d82c740, 0x1f01231b, 0xd932f595, 0x550fbcad, 0x97ac41c6, + 0xe3f006dd, 0x7f472baf, 0x23370a6e, 0x1e3c1b5c, 0xfafe72e8, 0xb71a9ba5, + 0x4b0a293a, 0x12297f5f, 0x374e29e2, 0xbc048dad, 0x192f76d3, 0xf7101487, + 0x25e8fb50, 0x134e1ee3, 0x134b03c6, 0xeb237155, 0xcb71b863, 0x3fdfc83d, + 0x274787c9, 0xf3c6f3a3, 0x5e5c422f, 0x2f33e6eb, 0xfecb78c2, 0xf045ee79, + 0xc23b26cf, 0xad0f60cc, 0xc630e57c, 0x7f7a8935, 0x627a6449, 0xe12fcbdb, + 0x31db6a3d, 0x35b7afa6, 0x6dbe429e, 0x78c7ed7b, 0xd85af388, 0x0efe8858, + 0x2414b70b, 0x02e72090, 0xbadf0291, 0x4d1e20ae, 0x755daf4d, 0xfc8fd0bb, + 0xe837a52c, 0x9638dea1, 0x171672da, 0x2bf1e164, 0xfdc7821b, 0xd4abc405, + 0x1c3f1c4d, 0x3a75e2ec, 0x415c85ab, 0x4a21cadc, 0x4057bec7, 0x728f0dbf, + 0xf4e0fe7f, 0x50bf0b3b, 0x2a26353a, 0xd7ce56e3, 0x9fcbf9cd, 0x262eaf21, + 0xfb8adc64, 0xe226f00a, 0xda24570a, 0x6c3c82f6, 0xc62afcdd, 0xc6dd0109, + 0x6db689d2, 0xf1069f3c, 0x8eba2d98, 0xc1efdce9, 0x25acf70c, 0xfd70478d, + 0x10f96db4, 0x8f08f6e3, 0xde236bef, 0x258f161f, 0x89ae79f1, 0x1c2ef160, + 0x030f10ff, 0x3bf4d0f7, 0x7c617b8f, 0x4261e22c, 0x4c5cc1c5, 0x2df6ceec, + 0xbe58ef1e, 0x2b8f38e6, 0xca4bd1f1, 0x5f353a05, 0xe048be32, 0xb8780cc1, + 0x2bae3fc9, 0x3791bc78, 0x0bd38ffe, 0x5cf107e8, 0x0a2db8de, 0x3a58430f, + 0x83c88242, 0x1e2c55b6, 0xe3ff7d4c, 0x3843cfa3, 0xd152ffaf, 0xf433cc59, + 0xd3ad9239, 0x6aff8dcb, 0xd12673f1, 0x127388a2, 0x10bd6a78, 0x26a78e5c, + 0x67eafdb1, 0x00b6b7eb, 0x092536fd, 0x66badbf4, 0xe62b7e85, 0x05754adb, + 0xafadef90, 0x960c77b0, 0x3942eed5, 0x141796ae, 0xf760b62f, 0x98937d0d, + 0x67a8aa9c, 0xe6eb44fb, 0xb6899708, 0x6df7fad3, 0x1b15cfc8, 0x8fb0f59a, + 0xbaff59ef, 0xb317f99e, 0x84fb03f5, 0xadfc6fcb, 0x8d99db7f, 0x09fa1b72, + 0xbce1d742, 0xe086ca9f, 0xf86e54fd, 0xa94fd146, 0xfccf56b3, 0xdfdd2e8d, + 0x126dad69, 0x49ba77b4, 0x7269a607, 0x6df996ba, 0x24b7fba9, 0x4abdf8e9, + 0xa8f7d70d, 0xc83f47bc, 0x9c271e61, 0x51c3735b, 0xc5e6b63e, 0x35a45da3, + 0x6965af55, 0x7fff842f, 0x935bfbdb, 0xbfac8d72, 0x371f1851, 0xd6e8c62e, + 0x8073f5d0, 0xaf513fbf, 0x00fff677, 0x8707cfee, 0x78e3dfa1, 0x4dbefcc9, + 0x6827bc0a, 0xdf3537dd, 0x5f781d92, 0x91912ad0, 0x65279512, 0xf0a59acd, + 0x0fef6aed, 0x477d16ca, 0xa19d1de0, 0x78102e8b, 0xefeae7df, 0xb3a29a13, + 0x70b7602d, 0xfa6d812c, 0x829ad6a6, 0x597216ae, 0x0edcef3f, 0x67b012d7, + 0xdec0b88c, 0xba4a18b7, 0x4daae158, 0xfccfddca, 0xbeaa79be, 0x31ae9877, + 0x83ddf4b9, 0xe7909fbc, 0xdc82481e, 0x867b8837, 0x8ac730e4, 0xf71081a4, + 0xc01beecf, 0xe4f915f3, 0x3fa6c7b7, 0x3081e780, 0xe71573f4, 0x27f58d99, + 0x9fac60e3, 0xb93dc537, 0x34af7e9d, 0x79f8877f, 0x8f9f8932, 0xf28ac4ac, + 0xf50f7e4b, 0xfb25cff8, 0xfb8a49b3, 0x08b9ef58, 0x63efabbf, 0x8cee7f85, + 0xec276597, 0x0dbf85a3, 0xc608781b, 0x03961751, 0xc31fd8e3, 0x980641fd, + 0xf1401f6f, 0xf5cb7673, 0x5b3fe039, 0x9eefb5e4, 0x88bcbd47, 0x338963db, + 0xafd876f3, 0xd7bd848a, 0xdcf961e9, 0xd9febbde, 0x3ac3b7de, 0xa1c1fe14, + 0xa2c56de4, 0x421f9137, 0xda12cbe6, 0xa6e4c939, 0xbd3f22b4, 0x072e4df9, + 0x397efdc4, 0xa78b0bf7, 0xf68dc8d3, 0xbc5791f9, 0xba46e611, 0xcec4d97e, + 0xe976dbc5, 0x09af1d99, 0xa78f21cf, 0x7c02de3a, 0x81da2c55, 0x762626f8, + 0x6c96396e, 0x1d31fee6, 0x0eae5099, 0x6eb027ce, 0x7da184b6, 0xd1eb4136, + 0x2ab8e95b, 0x8bf4128e, 0x33c7c638, 0xd40be9a8, 0x70e6bff7, 0x37e67ad7, + 0xd7c3c6a1, 0xf1aa1149, 0xc60c37bf, 0x2231f02f, 0xfdc2d49c, 0x958f9d30, + 0x98aac7cf, 0x814fd78f, 0x6ff74bd6, 0xebf0a2d7, 0x5b2af312, 0xdffc49d4, + 0x1c5d6ad3, 0xe311df7c, 0x97dbdf56, 0x840f7698, 0x2ae4a37d, 0x02a7fafd, + 0x3e01c46f, 0x871eaa59, 0x7ee32d3a, 0x17efea1d, 0xf67dc492, 0x7fae3b2f, + 0x69bd7bb7, 0xf9153b55, 0xbbed1633, 0x713f7ba2, 0x75bff71f, 0xdeea17ff, + 0xf66ec1ef, 0x8e946ecc, 0x29fcdfe3, 0x9df108f3, 0x1105eddb, 0xbe51c718, + 0xc8156135, 0x7e470fe5, 0xc2f60f14, 0xf71231fd, 0x1cb4bde7, 0xf7bb52b9, + 0x717bd567, 0x393f625c, 0x5846ed51, 0x3a9f076d, 0xa7bc31e2, 0xdb2dfc1e, + 0xb05e8637, 0xf2c9b91d, 0xc231edf3, 0x32ec230e, 0xd4cf3b6a, 0xefe4666e, + 0xec29bfe9, 0x9417fcca, 0xac472e7c, 0xffdc83d1, 0x17ee7cb9, 0xd65d3347, + 0xe2877b40, 0xce89bda1, 0xb0475ee6, 0xc23de51d, 0x7b8e2e98, 0x73134e80, + 0x88863f99, 0x5b942a5b, 0x7a049c9f, 0xfb8c934e, 0x7ddfc2d7, 0x2ce7b7f4, + 0x34a8f481, 0x131ca277, 0x5eeb1774, 0x86a543f0, 0x14e7b1f9, 0x097fd058, + 0x57d811e4, 0x0d34746b, 0x299ee742, 0x3c600bf9, 0x0e3afded, 0x8abf024f, + 0x669dff2d, 0x09aebd41, 0xb39779cf, 0xbffd80df, 0xd73b105b, 0xe8393cb2, + 0x298977fb, 0x6aceff4c, 0xbbfbb0d6, 0x7aeb92f9, 0x347973b0, 0x39acaa88, + 0xe0192ee9, 0x559f963a, 0x2892e51e, 0x8c38359c, 0x851bdfe5, 0x88d3df71, + 0xf3fb0747, 0xa60af00c, 0xc1624ce9, 0xf1b11674, 0xba3ae5f7, 0x9cfeb44b, + 0x83f32306, 0x309e9e25, 0xfa10ec9f, 0xcc6eceef, 0x3bb7d3be, 0xf37ddf93, + 0x19fc7295, 0x726eff9e, 0xef9849fe, 0x67b66ee9, 0xdd1bed21, 0x704fe2b4, + 0x21a2dcde, 0x1a9df7a0, 0x9bb41bfc, 0x24df7a8a, 0x8dd8bfe7, 0x3124dbd6, + 0x23674aff, 0x1d22a78f, 0xb6f6fef1, 0xd60b93d7, 0x02af7b40, 0xae3c815f, + 0x29be462d, 0x935c3332, 0x457cec91, 0xca5da5eb, 0xf857d20e, 0x5c87c2f7, + 0x86e117ec, 0xfdba4f3f, 0xbeef3a61, 0x073dfa1a, 0x02d8e5c6, 0xf74beae3, + 0xff8c1373, 0x40a71e05, 0xdee0d2aa, 0x068bde6c, 0xc79bec0d, 0xbf03bca8, + 0xa7e0e3eb, 0xb94fd34d, 0xdce7f63f, 0xfc19bb1f, 0x927a69ba, 0xe7482dca, + 0x842560fc, 0x64c8e7f2, 0x95f2235b, 0x883bf82e, 0x21e726ef, 0xb4ebb31e, + 0xd7678fb8, 0xfae7227b, 0x377f65d1, 0xb59a1f16, 0x5848cbe5, 0xef666d4f, + 0xed126cbc, 0x73b71c6a, 0x0736efee, 0xb26ef5e7, 0xe7cc24ed, 0x01c764f5, + 0xa3feb76c, 0x753f04ff, 0x7fde3eda, 0x4f1d4bb4, 0xf102950d, 0xa37f9dea, + 0xe39fcd9e, 0xd3545379, 0x69bfa80a, 0x2cc0774b, 0x2c7ee2c9, 0x0527e804, + 0xe7b33fc3, 0x0c74378d, 0xf8d17380, 0xff50728b, 0x3fef3131, 0xf38b3a0a, + 0x286ba70e, 0xcf9287ba, 0x80cc78de, 0x442e1377, 0xe22f5c82, 0xbafa9376, + 0x6fd0079e, 0xe04caf7f, 0x27ca23dd, 0x498efe0a, 0x48807a66, 0xf8f51ab3, + 0xc6a6cf5e, 0x36ce7aaf, 0xce7a1d21, 0xe4e5e5a1, 0x507a15eb, 0xff1fe0d6, + 0x2c58a7fc, 0x92412f0f, 0x42aac8bb, 0x629af7b8, 0x4c36f9dc, 0xb9b99a61, + 0x66bdee10, 0x207b4a24, 0x1f49699d, 0xe25df705, 0x232b38dc, 0xecb00f6f, + 0xca116b58, 0xc4583ce1, 0x814bfb7e, 0x1eee1c31, 0x39a170bc, 0x92df0146, + 0x7f28ac98, 0x2287a5ab, 0x8dc64c7f, 0x9faf7c8a, 0xefbfb5bc, 0x47c0777b, + 0xc3b07747, 0x9ca079d3, 0xb4656b21, 0x396d66db, 0x148ddb74, 0x4eeeb71e, + 0x9b036c2b, 0xcdb8fe78, 0x4fd82e05, 0xb00a5de1, 0x3ee4b463, 0xa09fd4fa, + 0x5f7b2d31, 0x74611e63, 0xebfc6b28, 0x799b6028, 0x3da1e6c3, 0x8c9de036, + 0xd5dfc135, 0x52c1f610, 0x65e9ecc2, 0xbbf6d41b, 0x550ecc95, 0xe54faca7, + 0x3c827fd1, 0x0ef5bbea, 0x6e97f833, 0x3763fc1a, 0x64d6e790, 0x284bbc65, + 0xbff2f17e, 0x1fe03964, 0x17e6a1e7, 0xe9120761, 0x6e2c83b8, 0xc5e56ae1, + 0xf85e403f, 0xe57917c5, 0x31fb9e98, 0xc41278f1, 0x3f1f0f47, 0x628e4b4f, + 0x5aaf67e5, 0xd0b8ef0a, 0x13c4277c, 0x4b9db291, 0x85efaec1, 0xf32b3617, + 0x2996941f, 0x95d387e0, 0x65bccaf0, 0xad43f5fe, 0x66fa8abb, 0xefca83bd, + 0x39d8278a, 0x639f7024, 0x992ee8eb, 0x6fdb0554, 0x4a31fe44, 0x7853f40b, + 0xc70bed83, 0xfef47aba, 0xc96527fe, 0xbb3b4f4c, 0x7ddff1ed, 0x6de27607, + 0xce46fd04, 0x5cfb3146, 0x8d29dd76, 0x177ae406, 0xb36caf86, 0xec7e0347, + 0x4ee1c5ed, 0x9cac83f0, 0x24fe811f, 0x866ce17d, 0xbfedc9e7, 0x7843d1b7, + 0xbf09efe5, 0x03ff0f57, 0xd13f379c, 0x46fb1468, 0xff9589bb, 0x6cede48f, + 0xeb67c8df, 0x83d03a63, 0x974261cb, 0xe252e566, 0xeeb0cb95, 0xbf003e60, + 0xf78edcf6, 0xd37b009f, 0x5a3eb63e, 0x29e3fb89, 0x4cd8bfb8, 0x95a3ebfe, + 0x7e77b2d4, 0x427dec2d, 0x7218bf71, 0xd1aeecbd, 0xbf8dfbc3, 0x2279baf4, + 0x843bdf99, 0xc7071f5e, 0xdca93e50, 0x3b1afcc6, 0x4aefae1b, 0x804bd6fc, + 0x068cf69e, 0x6dc05af9, 0x3bfdfc0d, 0xd8a17c55, 0x17b58837, 0xf78b13fa, + 0x3ae80f3e, 0x541fa026, 0xc6fd16a3, 0x092ce816, 0x6fea9751, 0xfc5886b9, + 0x68dbebfa, 0xe62df940, 0x73666ed1, 0x3e78dbed, 0x8171de1a, 0xc3ea3174, + 0x87fd8a35, 0x58ba73ee, 0xec455810, 0x6370ec5e, 0xe1d03e42, 0x199c44b0, + 0x309a9839, 0x35fb9bce, 0x27fc244d, 0xffeb4331, 0x6fd0b6ae, 0xf3bc6cef, + 0x3e87d07a, 0xcee7bbae, 0x24fbf401, 0xe29b9778, 0xfb7740f7, 0x81df9834, + 0x73f4255f, 0xfa91fc2a, 0x77f7acfc, 0xf307e50b, 0x65dd80c6, 0xfe83312a, + 0xfa665e3c, 0xad8b7916, 0x2a37212b, 0xe868a6a5, 0x09e4f5ff, 0xbce99287, + 0x01fd1613, 0x3df569f5, 0x5bea95f3, 0x26b0f285, 0xebede81b, 0x6e7f1625, + 0x31577c65, 0x9393ccec, 0x7d508e40, 0xf28ff41e, 0x1ef89dfa, 0xe6dcfa81, + 0xe7d5abd5, 0xf38dabef, 0xedcbd00f, 0x7071c96d, 0x7877388e, 0xcfd40912, + 0xcd56f27d, 0x021f5477, 0xdc36b479, 0xa6aef8c5, 0x6fce94ad, 0xb364dac1, + 0xf6e78a13, 0xa2d6f162, 0xdba7f0fc, 0xcbf3437e, 0x83370a5e, 0x9d30bdda, + 0x818de138, 0xa37aab85, 0xdeafbbbd, 0xd006eaf2, 0xa1d65eaf, 0xe06bf45d, + 0xbd7f0a1d, 0xd81706f9, 0x2c69e783, 0x8cf7847f, 0xf9193ac9, 0x060bd4ed, + 0x1fe75fdc, 0x2bfb81e9, 0xa50b23ac, 0x4254a9cf, 0xfcdeb4cc, 0x5db193d7, + 0xaf7625f9, 0x02537f3b, 0xfa0aa1c6, 0x8610bcb6, 0xd9c591f1, 0xf4dcbdb5, + 0x47449edb, 0xbc1c4a54, 0x975ae7ff, 0xf054f144, 0xc01f4fd2, 0x537f36be, + 0x47cbd21c, 0x61fbe0e7, 0xb60f4367, 0x84be39ce, 0xef05fedc, 0x0653120f, + 0x87895f82, 0xeece77bf, 0x7db8720f, 0xd977cd4e, 0x7e32ffbc, 0xd840c3ce, + 0x67cff058, 0xdca24cf1, 0x628d14a8, 0x4f942d3f, 0x3e076c54, 0xf9e037ad, + 0xb82c35b2, 0x0a486a9d, 0x8c2b57db, 0x49ec2adf, 0x507e8b15, 0x322b13d8, + 0xe7bbde09, 0xbff4b12c, 0x71f7a697, 0xd9c4a7fc, 0x4a7cc387, 0xfadf1f6a, + 0xf9f1e21e, 0x7e813ffb, 0x3bd89af7, 0x7c31ef6f, 0x6f02ff0b, 0xbe0ec67b, + 0xf429570e, 0x476db6cb, 0x7f781db2, 0x382bfc77, 0x3c6d9f0f, 0x25a654f2, + 0xc7cc7ec8, 0x658cec2b, 0x60fede30, 0x4b8db487, 0xb473b3f1, 0x5efc1d7f, + 0xeeaff44b, 0x53646cf7, 0xb6dbbc36, 0x07698200, 0x46cff2fa, 0x3ec36537, + 0x4437fc2b, 0x14cccedc, 0x4a947fee, 0xfbc44352, 0x0b8949cc, 0xdf83ef1a, + 0xe7de3aaf, 0x19f78b3c, 0x7de333fe, 0x0c9f393a, 0xef1e0988, 0x5fcf04f2, + 0x43d96a42, 0x43ee5c72, 0x077f0dd8, 0x67bc5658, 0x8899e5c9, 0xc0da18f3, + 0xb943ffec, 0x6364ab1f, 0x88432e71, 0x7aa7b59b, 0xe5640597, 0x89119054, + 0x113ae237, 0xc606fdef, 0x7be13425, 0x0e9337cd, 0xacc46d4c, 0x1ba29485, + 0x8ec491d3, 0x855228e9, 0x835268e9, 0x16a46de9, 0x09a4b1d3, 0x8dc7d253, + 0xff78c7ef, 0xf3adc67e, 0x0cffb034, 0x6f5c1498, 0xbfaf837b, 0x5243e04b, + 0x9578afbc, 0xd84518f8, 0xf121c5fb, 0x7e819292, 0xea2f0258, 0x9c31bfbf, + 0x119db078, 0x80f651b0, 0xef0594f3, 0x0d880a4f, 0xc42bc2e1, 0xa1c7ae47, + 0x2532f665, 0xe0e9025e, 0x1bd4854c, 0x19ee4607, 0x2b038ca7, 0x5e718719, + 0x5cec39fd, 0xe26ff2c0, 0xb1f79de5, 0x2824507c, 0x82ca45fc, 0x5c71fe71, + 0xef190f72, 0xb187261d, 0x6ef17ab8, 0x4230e4c9, 0xb5bf809a, 0xcf9438ce, + 0xde297a8b, 0x392530f3, 0x355ca00e, 0x142d23ba, 0x16670b7f, 0xb1c6ffa2, + 0xdb8dcb38, 0x7e3c5f25, 0xd75b0a4b, 0xc4aaa547, 0x8f1e743e, 0x77dfa7e4, + 0xbfafba7f, 0x04e7e82b, 0x3f755bac, 0x3c3ac46f, 0xf6313fd0, 0x2cfcf3c2, + 0xde6cafbe, 0xaadb343c, 0xaccd7e81, 0xdd67dfdf, 0x32cd3f77, 0x424edaa7, + 0x821496f9, 0x5da44deb, 0xf02dece2, 0x893bc45d, 0xbf33edef, 0xbe26eadf, + 0x531faa38, 0x5ca1671c, 0xd693c6a5, 0x571d0e5f, 0x5c46c4b6, 0x655be47a, + 0x2e3a993c, 0x3df7b68b, 0xee52abcc, 0xd3fc0b98, 0xfe91f516, 0xcaefea2c, + 0x1dc6acb8, 0x687114fb, 0xe3781d62, 0x1c593ad0, 0x438850da, 0xbff1f48b, + 0x7c134388, 0x10c3d62c, 0x72c34388, 0xf281cc37, 0x813a3fc3, 0x4e236871, + 0xda1c7878, 0x9a1c6511, 0x159ffbed, 0xb1de2687, 0xbd85b058, 0xdb80bfa7, + 0xfd060077, 0x5f7894e2, 0xc4579f86, 0xdf7ca4b9, 0xdf9eecdb, 0x041bff49, + 0xa7ec907e, 0xe859f9f8, 0x0fe0122f, 0x0cb5c279, 0x0fe01dc6, 0x09aff2a9, + 0x568277fd, 0xe9fbf506, 0x2bcfca93, 0x5c219f7c, 0xcbc7997f, 0xaec0fcc0, + 0x8f51a0b5, 0x1782d1fa, 0xfe82b3ee, 0x64d520b4, 0xf2b77945, 0x514be43e, + 0xfccf3c9e, 0x9b7ac473, 0xdea09cbf, 0xac4f3de5, 0xeff0d833, 0x404bac23, + 0x3e7bcafd, 0x0814f6e7, 0xebfb84d3, 0xdd1d514d, 0x536ddee1, 0xf4158663, + 0x5b220fbb, 0x71b14256, 0x5e9f0ce1, 0x0e98797d, 0x9603aff5, 0x74888298, + 0xf3b13adf, 0xf99e4275, 0x3af98335, 0x7bb136b3, 0xf6a39c85, 0xdc0b4882, + 0x84fbb02b, 0xefc12d41, 0x4ae7c7a9, 0xc08a7b8a, 0xcb16c9f7, 0x7fb8255d, + 0x6a10f760, 0xbfb8bd3b, 0x2985b22e, 0xdd423fee, 0x0ef38b67, 0x1e89efdd, + 0x118d7bf6, 0xc48337fd, 0xf7233dd3, 0xf663bdf0, 0xf3c0e48e, 0xa6c61dd0, + 0x4fabe034, 0x53731c63, 0xcb6e20e3, 0xce39416a, 0xf17ceae3, 0xbca06f40, + 0x073ef114, 0x20e32da5, 0x54deea1e, 0xa3d40547, 0x067b30d3, 0x9947def9, + 0xc5f27b99, 0xa7682dd7, 0xb7f54caf, 0x3bbff3d3, 0x1e2f5ea2, 0x59e3058d, + 0x5095bf9c, 0x8d0338af, 0x15f3c60c, 0x8a674ff2, 0xdbf98729, 0x4adefeaa, + 0xdfe5576c, 0xf167a95b, 0xad89a50d, 0x59b3af4c, 0xfa6e2cad, 0x959dfde7, + 0x9553ddcb, 0xf428b626, 0xe621b255, 0xbea6ec8a, 0xfdae5df9, 0x5a7f6c36, + 0x7e0a87d5, 0x98e8b198, 0x3a66cf82, 0xb5f9959b, 0xaf7838d2, 0x1567d28c, + 0x35b3c7d0, 0x0b14d469, 0xf01801f8, 0xf7cbbf5d, 0x77f11a7b, 0xcf09baa2, + 0x9f5e628b, 0xd8451f55, 0xc651ed53, 0xa979f067, 0x704f8bfd, 0xdc1399bf, + 0xf704e66f, 0xfdc1399b, 0xbf704e5a, 0x7c87e116, 0x4c8aa242, 0xe47f5074, + 0x828f8137, 0xc23723f8, 0xc8fe90f7, 0x0a71c7e4, 0xb7e7647f, 0xe47f0b08, + 0x91e7a95d, 0xec9bbb8f, 0xc43b436f, 0x9ffbd1e6, 0x23f943bb, 0xeeca9fbf, + 0xa5503e93, 0x22f3d29f, 0xb4f1a9fa, 0x0bd95e50, 0x37ac59df, 0xcb879010, + 0xf1a6d924, 0xb0f18fbf, 0x16ce5377, 0x1dfc28a5, 0x8b7f962a, 0x0f7e17f8, + 0xd0196f39, 0xdf7ca04f, 0xd7405ec1, 0xe71d53c7, 0x1dfd9952, 0xab2e87df, + 0x5fbfb033, 0xbf21cfc7, 0xebf139e0, 0x718181d4, 0x77e6a114, 0x53d34e76, + 0xe55e7499, 0xef153b91, 0x8af18b22, 0xfa718979, 0x5f8cb9da, 0xc50ef2c9, + 0xf6db6b3a, 0x63e02f48, 0x9c167ef1, 0xa904275b, 0xe8c69f1f, 0x5287cf42, + 0xa4bfed1a, 0x7d0f9d8a, 0xffb9adf4, 0x3ec7a013, 0x509dca13, 0x2cf3d5f5, + 0xf10fb1df, 0xd2173ea1, 0x0b4d7679, 0x3b9fcf32, 0x6bf5abbf, 0x4e217437, + 0x715097e0, 0x9b250751, 0x2d77c605, 0x4b5e96bd, 0xd2d7a5af, 0xf4b5e96b, + 0xbd2d7a5a, 0xaf4b5e96, 0x6bd2d7a5, 0xf4e5ffe9, 0xfffd007f, 0x8000c102, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x30001131, 0xafb00408, + 0x521cae88, 0x11447fea, 0x992c9a42, 0x326ebaf3, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0x7f6db6db, 0x98a102fc, 0x80005382, + 0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00002000, 0x000040c0, 0x00006180, + 0x00008240, 0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, + 0x000146c0, 0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, + 0x00020b40, 0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, + 0x0002cfc0, 0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, + 0x00039440, 0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, + 0x000458c0, 0x00047980, 0x00049a40, 0x00008000, 0x00010300, 0x00018600, + 0x00020900, 0x00028c00, 0x00030f00, 0x00039200, 0x00041500, 0x00049800, + 0x00051b00, 0x00059e00, 0x00062100, 0x0006a400, 0x00072700, 0x0007aa00, + 0x00082d00, 0x0008b000, 0x00093300, 0x0009b600, 0x000a3900, 0x000abc00, + 0x000b3f00, 0x000bc200, 0x000c4500, 0x000cc800, 0x000d4b00, 0x000dce00, + 0x000e5100, 0x000ed400, 0x000f5700, 0x000fda00, 0x00105d00, 0x00000028, + 0x00000000, 0x00100000, 0x00000000, 0x00000000, 0xffffffff, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x65e21f09, + 0x63e62860, 0x88237860, 0xcc2b4e2a, 0xfe9942ce, 0x0c0cccf3, 0x32f88117, + 0xe2055f10, 0xe9a48cd3, 0xb045e2b7, 0x30327377, 0x7df90358, 0x9b8b5a40, + 0xc8014181, 0xb3e201b6, 0x204bfe40, 0xadc40afe, 0xdc0c0c3c, 0x6a0c0c5c, + 0xc4042c40, 0xcdf8bcb6, 0xff2023b7, 0xaf951b9f, 0x17ca83cd, 0x3fafc6e6, + 0x7cbf0789, 0x6c790106, 0xf928b3f8, 0x4620e1f1, 0x2d43749f, 0xca86aeac, + 0x6065522f, 0xe7c40df8, 0x681ae2a1, 0x10aac5f2, 0x03329cfa, 0x7e1ab243, + 0xc80853b3, 0x000c060f, 0x4022bae9, 0x00000400, 0x00088b1f, 0x00000000, + 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x27bcce66, 0x20212793, 0xf0841e4c, + 0x04242074, 0x11093a8c, 0x5076c403, 0xc2ab16fe, 0x25786784, 0x5ae5a911, + 0xc0133bff, 0x51b91688, 0x7e2da5a8, 0x68bc104e, 0x01226f69, 0x903a4483, + 0xbd08a5c0, 0x168b6ad1, 0xe088786d, 0x7e929205, 0xcfe956de, 0xe7dad6bf, + 0x9939cccc, 0x77e8f881, 0xbf41ffbf, 0xdecfb3ba, 0xd7b5ef67, 0xcfb5ef5e, + 0x30733d1e, 0xd7632776, 0x73941ff1, 0x4158c645, 0xf81d0ca4, 0x614b3ce2, + 0xc18b72ec, 0x6c64cc65, 0xe8431eca, 0x68afa84e, 0xd7588214, 0x3633301d, + 0x5b2bb181, 0xec46bd79, 0xb41b78dc, 0xb645d7b3, 0xd3b60a03, 0x8c8563a6, + 0xfe31379d, 0xb1d76f4f, 0x9916c634, 0xe3457579, 0x7e3839c1, 0x9991ab55, + 0x2df3fde1, 0x2beb07a2, 0x26410877, 0x27befb40, 0x7f180ca5, 0x32685071, + 0xe3bea0bb, 0x6765c959, 0x2f81cd6c, 0x0abce0ae, 0x4dfa9f5c, 0x7c2125cc, + 0x8d75a5ef, 0xb0696c66, 0x8c066a79, 0xe09774b3, 0x4b3cc1d6, 0x3ba10ab7, + 0x2173e027, 0xcbb8c228, 0x2b995a76, 0x9d70c38f, 0x8eb4bcd1, 0xbcc02f95, + 0x83670899, 0xe647b5e4, 0xa9f3f053, 0x72b981bf, 0xaf15f523, 0x5ef03cc0, + 0x3704aff5, 0xc75ab12e, 0xff304d7c, 0xd9e67d95, 0x7d70d92f, 0x3dae5275, + 0x7b951d7a, 0x834b1d71, 0x1b54d28d, 0x2d28d5c2, 0x6f191d1a, 0xcc4dced9, + 0x6b828a65, 0x5f00f64b, 0xfcb6bb54, 0xf054cfd4, 0xd3cc652c, 0x83f84364, + 0x9131ccd2, 0x22422de7, 0xbe38a963, 0xb19f1aa8, 0x99173d00, 0x6778843b, + 0xf477766d, 0xaa755dbe, 0xa2656df7, 0x781c6efc, 0x87de45fe, 0x2a4efd67, + 0xa9d3f937, 0x45dfb1fc, 0x9fc4fe70, 0xfd4fe547, 0x73fe7a6e, 0x2f95117f, + 0xbe543df8, 0xb2a72fe8, 0x7ea5efd1, 0x5367f92f, 0xa3efc3b9, 0xafeaffe7, + 0x7f15f2a2, 0x85ff3d2d, 0xbf95357f, 0xf9e807f4, 0x53d7f9bf, 0x04fb8cd9, + 0x16ff6ee5, 0x83f8f72a, 0xff75efd4, 0xf9f72a4e, 0x33f9e89b, 0x13283f88, + 0x3d3ace3c, 0x19424fec, 0xb0790273, 0xceb7af64, 0x59e4f500, 0xd7c03ebc, + 0x7e012750, 0x3a802c06, 0xdaa0dfec, 0xb4233ace, 0xdbc55a0f, 0x6b9c0687, + 0x743ed04c, 0x6ecf6f1d, 0x4331aef0, 0xde66f67b, 0xb0d83c3e, 0xc3ed02c6, + 0x51f6f3b7, 0xac6b9d4d, 0x85aa3ed0, 0x721adfb7, 0xfd41b5ae, 0xcf5e0ed6, + 0xb5aef4ef, 0x5dff3d43, 0xd5d89f5e, 0xef01d6b0, 0xdfc73c4f, 0xd9bde2d7, + 0x60cf9ce0, 0xee0736af, 0x4207e8f2, 0xc23e725d, 0x1cbd8cdc, 0x77d516f8, + 0xded4dc1b, 0x47aef81a, 0x92ea093f, 0x058fda9b, 0xc7bed47c, 0x53f6a5e0, + 0xbed42581, 0xfb52f247, 0x6a4ac095, 0x4b50dd7f, 0x87eeaced, 0x54bafed4, + 0x7549ed4b, 0xcfbea8eb, 0x8c196d00, 0xe33dd4e5, 0xcdfd0009, 0x511b7c11, + 0x6aeb747e, 0x12ca18ab, 0xf91d287d, 0xcd8149e9, 0x5d80fe46, 0xf27bba23, + 0x7c83c916, 0xc29bfcd7, 0x994cc497, 0xbeb052d6, 0x05a7e5e8, 0xd827e71a, + 0x71825baf, 0xce3e6fb2, 0xaa4563b8, 0xab1dc671, 0x1209c652, 0x8dfe963c, + 0xb26c7cd3, 0x4b639e1a, 0xa15e7195, 0x5bfd1c71, 0x8ab7b8d7, 0xb5bcf0d5, + 0x35e7195c, 0x7fa9271a, 0x1b7eecf0, 0xc64423f0, 0xe036fdd9, 0xd9c69327, + 0xf5a4e34f, 0x77fc9e0f, 0xe4e3548a, 0x8ca553bf, 0xce7841d3, 0xbb38dfe8, + 0x86ac99df, 0xcaa59de7, 0x9c682738, 0x575bfd21, 0xd58aeffe, 0xb96efcf0, + 0x69efce32, 0x8dfeac9c, 0x357de7b3, 0x3f79ecfd, 0xa27f3f4c, 0xb7fb7271, + 0xd40f82ae, 0x41f053f4, 0x102e7e98, 0x6ff6479e, 0xa81f3d9c, 0x07cf67e9, + 0x33f9fa61, 0x7fb633c1, 0xa3f82aeb, 0xfe0a7e9a, 0xcf9fa618, 0xfdf19e09, + 0xd3f5e783, 0x7ebcfc6a, 0x511f8c3a, 0xfb0a7840, 0x33c4cf07, 0x3c4cfc6a, + 0x8d8fc613, 0xbfdc99c6, 0xa33f5e71, 0x67ebcfc6, 0x1549f8c2, 0xf4775d70, + 0xcf135d6f, 0xf133f1aa, 0x433f186c, 0x19529e08, 0x8ce3061e, 0xbece3f89, + 0xecfc6a8b, 0x33f1c8bb, 0x3a27d3be, 0xce90dda0, 0xe4ce08dc, 0x0080de0b, + 0xa814faed, 0x30f4b0bb, 0x3d3bc81f, 0xf8d1ddea, 0x84405772, 0xc4aefb76, + 0xa2bb4ff1, 0x58e96ff5, 0x8263975c, 0x3877654e, 0x7aaa2d8b, 0x4a925952, + 0x6454a73f, 0xb369eaa8, 0xf4f554b2, 0xdeaa4707, 0x5e3058cf, 0x7cbc1f55, + 0x643eaab2, 0x7deaa955, 0x55d3e3d7, 0xeeeb59ed, 0x3673d555, 0xcf554f7c, + 0x554f3cdd, 0x54badbcf, 0xedc8de35, 0xd1f5552b, 0xd5531ebb, 0x51acb6c7, + 0x4f6dddd5, 0x3be3eaab, 0x3f8d539e, 0x54cff8e1, 0xb777c2f5, 0xa745eaa9, + 0x3fbd555e, 0x1a6bdcf9, 0x3ce6c6fb, 0x8bae4a3f, 0xc95acf68, 0x910e33ce, + 0x192d5ec8, 0xa3faa262, 0x7f546c43, 0x70df0ef4, 0x8fe3ec27, 0x6bd005f0, + 0x5bbe4a8f, 0x2fec319d, 0x4b1d39d8, 0x63a7d2c7, 0xd7db7d45, 0x80ce801b, + 0x5e874a2e, 0x650d3dcb, 0x3727ae8d, 0xe8dfca11, 0x2e916a4a, 0x4474151f, + 0xd591567f, 0x8d58dd22, 0xfd70e88c, 0x0297c2b0, 0x54f87451, 0xcaf39726, + 0x6a194fb8, 0x3eef51d3, 0x0066f756, 0x9993f2f5, 0x664cbc60, 0x9bc287ec, + 0xbc0e40a1, 0x3a68f99f, 0x09268bda, 0xf9e8d0ec, 0x347f9825, 0xf9c01fcd, + 0x6fcce3eb, 0xcd522dca, 0x52aace6f, 0x60966fcd, 0x4f63277e, 0xe7961dd7, + 0xffde9137, 0xe6987091, 0xa6ad6537, 0xac4bd7f9, 0x25bf354a, 0xf2037f3c, + 0x7f38f3c1, 0xe7f58c41, 0x3faf564e, 0xfd7aa96b, 0xcfff5f12, 0xf3c84eea, + 0x3ffd685b, 0xf5f04e17, 0xd7c63d67, 0xa371846f, 0xf18477e7, 0x5ff9c41f, + 0x69bf338e, 0xfd7ab178, 0xebd5cbd9, 0x5ff9f237, 0x9e4f7bad, 0xfff346df, + 0xaf8f7842, 0x9a71fb3f, 0x75ac68df, 0x38c9a13b, 0x441b52d4, 0x2fe600b9, + 0x050c801b, 0xc6444cf3, 0xde0c6248, 0xd164285f, 0x016a3c3e, 0x9ffe83ba, + 0xd0de8059, 0x72ed977e, 0xd017ac16, 0x6996af0e, 0x4aaec17a, 0x657819e9, + 0x57f72b41, 0xc333f818, 0xad2bbe00, 0x11fd9fbd, 0x7db05de0, 0xa025c91c, + 0x2def8674, 0x23529794, 0xe6307c72, 0xe413321d, 0x877bd329, 0x9a863bdc, + 0x2fd7683c, 0x1f630466, 0x60d85e3a, 0xc515df38, 0xa8b78b6f, 0xea824beb, + 0x097702ba, 0x81940912, 0x0b579652, 0x7f079ef3, 0x7ddd8180, 0x2c6dec06, + 0xb9b0313f, 0x0e7e785e, 0x452605fc, 0xed1d55f3, 0xabbd79cb, 0x73d61d3e, + 0xc3704abe, 0x0d81ec88, 0x3a196395, 0x7bcf0172, 0x77ef0039, 0x852ff298, + 0x7273e9d6, 0x003617f8, 0x7ff1477f, 0xb0bbc88d, 0x0ee08517, 0x7fbfe790, + 0xba054573, 0x83d7d0bc, 0x5e577def, 0xc92de2f7, 0xde98f7aa, 0xa9cdef44, + 0x1ea20c4c, 0xc36ceef8, 0x3b552eb9, 0xf1c03f30, 0xdd0fec91, 0xf1eebacf, + 0xdfb99e82, 0x75d7eea7, 0x8dd1eac0, 0xbb4b7285, 0x3dbec181, 0x8719a550, + 0x1f7f6879, 0xa878e192, 0x973edd56, 0x5fd42539, 0x9fab5773, 0xe3b40657, + 0xcf00f800, 0xf81c793c, 0xe6f844e7, 0xd7f36dcb, 0x7daa021b, 0x0a947a02, + 0xa22cf6e5, 0xbd0f5a02, 0x3fb7dd9f, 0x434041d0, 0xfb588107, 0xf9f7fffe, + 0xae7d8dff, 0x3e492d69, 0x8ad70517, 0xe7c969a6, 0xdb2dfaa2, 0x5f555339, + 0xd55fbc12, 0x4a96f17f, 0x86c2fb55, 0xf9f6aa25, 0xd5561feb, 0xa4ff032b, + 0x75773fea, 0xa1fdaa9d, 0xed54a7da, 0xab3d540f, 0xfbefdfaa, 0x77ffaaa9, + 0xdaaa3767, 0x864b0385, 0x46a8dc62, 0x881d0df2, 0x8df7aef1, 0xa1109b6c, + 0x2fae855b, 0xfca9d3f8, 0xb2a2efd4, 0xc830e50e, 0x5e3edd75, 0x1cab6cd6, + 0xa15bf28a, 0xb50c4ff3, 0x69fe5043, 0x672b55e9, 0x6325d0fb, 0x88bed083, + 0x2e596717, 0xf3ca2f30, 0x19db816e, 0xb213f3ca, 0x0d6c675e, 0x8972d7f1, + 0xd7f2dff3, 0x3f229606, 0xb942972c, 0xe3f8b6b5, 0xd68126b2, 0x1a36d8c1, + 0x10704967, 0xfbd17918, 0xf382ad9a, 0xe69141d2, 0x6e1f46af, 0xdec1da12, + 0x3f9c3a0d, 0xbee43ed4, 0xe78f0831, 0xc1c01d19, 0xdf49535a, 0x2797f25d, + 0xfe23d39f, 0xf05e54bc, 0xbcf2a6cf, 0x39e547df, 0x6795157f, 0x7654b5fc, + 0xf95357f9, 0xe5403f91, 0x2a7aff29, 0x5037f03f, 0x85bfd279, 0x83fbdfca, + 0x7bf15e54, 0xf4e854a8, 0xb57d96ff, 0xf2bdb8e8, 0xffafb8df, 0x16afbd1e, + 0x23c3939d, 0x0d06ebef, 0x55794abc, 0x61797027, 0xf31676e4, 0x788e2958, + 0xc3078955, 0x94571448, 0xf0ddc1e3, 0xd3f62777, 0x1831e537, 0xcfe8eaef, + 0x7b8e3173, 0xb191a4f5, 0xd3ebf8cc, 0x3c5c5fee, 0x46ee80b0, 0x3858b7f8, + 0x72aa015e, 0xdcec1e36, 0xf3dd7b11, 0x92cf5d78, 0x7726fdf0, 0x3c355c74, + 0xc072e22e, 0xd16af1cd, 0xdacf7b71, 0x847c722e, 0xb3efbb76, 0xc6b5e847, + 0x718b93d8, 0x2347f662, 0x36c63d43, 0x055871cb, 0x575e015f, 0x3a7ff5f0, + 0xfda04e3e, 0x1f1f105b, 0x47e0a5dd, 0x32bff0c4, 0x574aafc5, 0xae90439d, + 0x7bf4cab6, 0x027865b5, 0xe7191d1b, 0xd38b9d6e, 0x7ef04df5, 0x0e4be8f5, + 0xa657f3b4, 0xf2e79ceb, 0x456fe3e3, 0x16d3a653, 0xaab4a76d, 0x841b57eb, + 0x70371e72, 0x831acc25, 0x3ce9d1f2, 0x2c728397, 0x9c654a9d, 0xf392e995, + 0x0bf6325c, 0x2576f872, 0xea7e5f12, 0x6fbf5137, 0xe3788e1a, 0x6168e044, + 0x247de167, 0xf1d9ebd1, 0x3ba5c7fb, 0x8c245ffd, 0xc336b0c7, 0x985f6867, + 0xd1d7ffe0, 0xaa7a63ee, 0x34d6e32b, 0xade30189, 0x6a977cf8, 0xa5cf783e, + 0x67ae94e4, 0xf5be88dd, 0x7f42bcec, 0xa0e7ca20, 0x1079489d, 0xbf6d53b3, + 0x35eaaa24, 0x2a9d03ad, 0x00ff067b, 0x04cac739, 0x72c1d23d, 0xf5ba2c99, + 0xc002f5b6, 0x2e9d0937, 0xf78147a4, 0x92ea615b, 0xafa42e7c, 0xcdb9dfb5, + 0x681b3d85, 0x60f85abd, 0xf5ea66ff, 0x265fe1f1, 0x1bd47d5e, 0x22d7fe83, + 0xd01ea3fd, 0x999f3f71, 0x43e40e02, 0xdc701e96, 0x6cc3fc4b, 0x9ae0fc61, + 0x5513cc19, 0xff01c657, 0x5f6d47ad, 0xa4bbbe72, 0x76bbfee3, 0xbcf2cdde, + 0xf55fc337, 0xe2a7b7ae, 0xac78b5ba, 0xe4b3fd6e, 0x5314fca3, 0xefc151e1, + 0x59bbd124, 0xee97f984, 0x7f212d3c, 0x7204305d, 0xb903787f, 0x5b7e17df, + 0x646b79fa, 0xd8f72b9d, 0xf95fbec9, 0x0bd79cac, 0x779c4eb0, 0xf13c915e, + 0x0515e835, 0xa67c6807, 0xd3d88c2b, 0x5e6d7e4a, 0x27f232cb, 0x0901663e, + 0xc51792e3, 0x9fb44286, 0x4a353697, 0x32f3801e, 0xbe2395d3, 0x1c77b32e, + 0xb5fb51f9, 0x9f08944f, 0x899f6760, 0x6cec1386, 0x6cec1d55, 0xbb117d55, + 0x51f30d37, 0xc01b368b, 0xaa75a7c5, 0x9d115fda, 0x5662ee34, 0xc9768f5b, + 0xeffc96d9, 0xf0fb86dc, 0x88850bfa, 0x3cd079df, 0xf8f10928, 0xcbf1e136, + 0xdf04bfce, 0xde77df1f, 0xf26add08, 0x561e328e, 0xc13c14ec, 0x44737418, + 0x7d0ad796, 0x5f8641fd, 0xc59c0f89, 0xdea4417a, 0xa17fa9ad, 0xfe657fa9, + 0x4bba014d, 0x24f7ec8b, 0xe91677d1, 0x38f906ad, 0x5fb7c221, 0x3ef4fc79, + 0xa37f77e3, 0xf3560fe3, 0xc5ff8c0d, 0x4e7e3a37, 0xfa8df81f, 0x77e3be82, + 0x59631d9b, 0xc4a9d902, 0x3a71815f, 0x1fe9bbf2, 0xd2136bda, 0xc0a69fc9, + 0x39ddd638, 0xd9a38c41, 0x14e99dcd, 0x54bf07d7, 0x6024f30f, 0x0edf907f, + 0xf9f016e6, 0x2cd37ed3, 0xf8ca8794, 0xe55eb776, 0xe914267f, 0x7b28fe35, + 0x61f00737, 0x38a6a793, 0xfcedd41b, 0x5b6b666f, 0xe30b7c4c, 0x04e8fca8, + 0x2ffe45d6, 0x9e7aa78c, 0xa1d59a38, 0xa8f44a1a, 0x6d154f9f, 0x9c4b6f14, + 0x9c4e28c6, 0xfad7ae5c, 0xd2c315f7, 0x4740e0a2, 0x32c9ea1b, 0xcfa6e01c, + 0x67fde014, 0xf08cf4cb, 0xc5ff8012, 0xbc593380, 0x01f9c216, 0x39df155e, + 0x65f540f2, 0xe7aabc11, 0x4d19e700, 0xe50f207c, 0xb8b31246, 0x53801e71, + 0xdbd1eed5, 0x0e1e2853, 0xa3e517f2, 0xc989d4cd, 0xaaef9c7f, 0xf4ebaf0a, + 0x190b23e9, 0xfc385085, 0x942fa601, 0x83ef8bf7, 0xd313bfaa, 0x8f04d9d4, + 0xd8361c7a, 0x6f8f2d19, 0x8309fd95, 0xe9133bc1, 0xad6870aa, 0xa717f388, + 0xaec872bb, 0x3a214b68, 0xca5d5acc, 0x685d42ce, 0x9cf78460, 0x39ef1c0d, + 0xf71e3a3d, 0x0e09675c, 0x268cb183, 0x9c833016, 0x301cad02, 0x8259c78c, + 0x5ae49fb2, 0xcd3cc3a3, 0x7829a07a, 0x54a7adaf, 0xa73610b7, 0xfc609b09, + 0x3e3de96f, 0x67c1c63d, 0xe375d2fa, 0x9ae161f0, 0xa5a0c18e, 0xb8211b19, + 0x05080b41, 0xc2de8e87, 0xdf184a43, 0x790f4185, 0xd72ed46c, 0xdaed0859, + 0x2faf0b06, 0xae9417d7, 0x988ff787, 0x5d71cbbc, 0x891ce4cc, 0x4a162b79, + 0xb7c6f5a2, 0x0724024f, 0xb6f2b815, 0x4cb54d77, 0x2814fe40, 0x1ecc3fcf, + 0x24255bb6, 0xa5361dae, 0x6ed0921e, 0x2dbcb6f5, 0xa2bb7fa1, 0xd76a6de9, + 0xa1ca1d61, 0x07535dc9, 0xd4f88981, 0xf4d2b2ba, 0x4b5e3011, 0xd60eba65, + 0xb2badcf5, 0x4f75ea43, 0x1c51d35b, 0x775eb759, 0x77dd66b7, 0xcfdd70df, + 0x5d2eefe9, 0x75ffdc5f, 0x8b3fbec2, 0xa25199f8, 0xeefe510b, 0xf0282da4, + 0xec99bb78, 0xc69c7941, 0x1287f638, 0x7e718437, 0xe850eb8a, 0xa14f7947, + 0x9174789b, 0x79239ccd, 0x1f4d503e, 0x6d9ef4c7, 0x7a4bd708, 0x4054894f, + 0x787b25eb, 0x2ee7cf86, 0x2dd08fcb, 0xd1f2f9b3, 0xe61832be, 0x57e702fd, + 0xb2519ae0, 0x7802cc52, 0x21ec6177, 0xd49eb235, 0x2e7301d5, 0x03d533ac, + 0x7be177d8, 0xcf7c66be, 0x8427bb31, 0x32262647, 0x4620be5f, 0xaf995ee8, + 0xdf1e4dfe, 0x05d4afaf, 0xed5c90d7, 0x08bc7012, 0xe869743d, 0x43d387a1, + 0x87a269eb, 0x9cd3b6ea, 0x4aeb5a1e, 0xdbaa9e91, 0x85d1a704, 0x8719eaeb, + 0xebeffcfb, 0x61ea97e6, 0x7b5a879f, 0x1d0107ea, 0x69655818, 0x7af09985, + 0xb3ebe118, 0xca7c323f, 0x6fede2ba, 0x1facd1c3, 0x707d468d, 0xe61ee75c, + 0xe94de08a, 0xd12f4977, 0x7c906c3e, 0x295e90ef, 0xcb823aea, 0x3be8ed7f, + 0x1c5bb40e, 0x883defc7, 0xc1663bef, 0xf322b90e, 0x535f1c36, 0x1a67e78a, + 0x64381d60, 0xa009eb02, 0x1f1f13dd, 0xf8c25f9c, 0xf84d3968, 0x9e1d61d1, + 0xa7e72abf, 0x5ec8cf80, 0x7ee56a19, 0x1e7ac7ee, 0x5e9bfb3f, 0xef6e4b94, + 0x2abf1ea6, 0x5c4fd0b9, 0xa9fea3a7, 0x5e8e8e58, 0xf7ea3aff, 0x055e5437, + 0xfb287c11, 0x4813d0a9, 0x5fe62b4a, 0x577c5996, 0x6493f4d5, 0x4f1a8acd, + 0x9fa36f79, 0x7f8017b9, 0xde63b137, 0x81ff2823, 0xf543fe7e, 0x198318de, + 0x47f4a6f1, 0x3fb58cfa, 0x14331ef0, 0xd05c79f0, 0xa563b9bf, 0x7f617688, + 0xf650b5f7, 0xacad0b8f, 0xbf7835f6, 0xac4a0130, 0x01f5cb27, 0x2f107d72, + 0x75b94fb3, 0x946f3c02, 0x6e9effb8, 0x7a92e390, 0x3bcc48e7, 0x3db81ba5, + 0x923e9c58, 0xb7c2bee4, 0x2484be88, 0x58021b32, 0xe964f566, 0x3e14df70, + 0x42e8f7d6, 0x594a5076, 0x0dce977a, 0x61f98fcf, 0x9ff037dd, 0xbd108fa6, + 0xd1d1ecb1, 0xfcbf5d06, 0x5276b898, 0x6c3b1f57, 0xec9521b4, 0x42f78da3, + 0xaf447abd, 0xc6b5fb84, 0x8ddb7d5a, 0xe169efce, 0x13ed763f, 0x577bfa07, + 0x8f2c6afe, 0x5078f715, 0xff51dbc6, 0xb14f7a6c, 0x30ab68a3, 0x3ec0cfbe, + 0xd70bf0e2, 0x7d92548d, 0x3c890774, 0x3e80c7dc, 0x55a7f509, 0x777e73a0, + 0xebb3fa46, 0x8477e7c0, 0xb1b05696, 0xb72bf950, 0x3ff04c6f, 0xe98faff4, + 0xed1e747d, 0x9a79e318, 0x3b6d6b42, 0xd33199d6, 0xf985c3bd, 0xa29e753e, + 0x2ca1a130, 0x42489509, 0xc533cd26, 0x0e4f69a4, 0xb2fe51e8, 0xe71e4cec, + 0x945f3062, 0x44f40e9f, 0x7c3658f9, 0x3395d924, 0x65dd2af2, 0x48bdfbf2, + 0x731b7eac, 0xfae44426, 0xeefdd734, 0xd1dd9532, 0xfd3946e0, 0xe245dfd6, + 0x7f1e2d6b, 0x7d7ce065, 0x9775efd4, 0x63c5f4e5, 0x67584ba9, 0xa7c5f577, + 0xfc5a5f16, 0xc95fc3c6, 0x52597729, 0xf1693c0c, 0x46ff0c72, 0x06368f3c, + 0x9de20203, 0x4b98e9e3, 0x78188160, 0x29d2ec52, 0xa4683176, 0x9dd90f76, + 0x68f0c977, 0x4f17d6f1, 0xd2bb8a9e, 0x411ff022, 0x4e91e87c, 0x884aefdc, + 0xdb0304ff, 0xdd0ceb81, 0x6ab7f949, 0x434c1fb9, 0xf93bb579, 0x8375e150, + 0xf087707c, 0x386301bd, 0x6d55fd7d, 0xb83dde7f, 0x14a0dd72, 0xfb9803c4, + 0xd4671f1c, 0xf1b8c374, 0x7da4cd61, 0xdba8fc07, 0x587e3993, 0xcbbf6f32, + 0xd0d769a9, 0x0abd768d, 0x3e1bfcdd, 0x3f17d498, 0x30ecdd0a, 0x067276c8, + 0x1e788c1b, 0x02426fbb, 0x78da2dc5, 0x4f4b5ede, 0xc37a4f13, 0x47f4c8e3, + 0x5f3025f4, 0xfb33b9f8, 0x569bc86b, 0xf25166d0, 0x7be8b866, 0x51bc9623, + 0x7976fff6, 0x81676e9f, 0x4b03a283, 0x74c25ffd, 0xff591993, 0xda275c21, + 0x20d883e7, 0x8318e75c, 0x7969cb8b, 0xcb75e19d, 0xe58a09e7, 0xb64d8bf9, + 0x7acb8e10, 0xf8c297f4, 0x5cf8a2cf, 0xc08a4a40, 0xb3fb9061, 0xdb8cb521, + 0x79d20f5d, 0xbb0bc01c, 0xf1c08d6e, 0xa7a08307, 0xc70c9578, 0x80a69de5, + 0x57ac2b78, 0xf511fdf4, 0xf8e125d6, 0x3e9f5a58, 0x4a7a8b94, 0xdadbdedb, + 0xd0ed8d51, 0x93f5116f, 0x71865fe1, 0x9ea7a007, 0x6dc18d37, 0x8a48e231, + 0x4a6c093d, 0x83e15cf2, 0x6505513b, 0x92dfa5f7, 0x1c7af1d6, 0xa5b74b5f, + 0x1da159e0, 0xbbd7a5aa, 0x7c1ccf58, 0x4553a5ae, 0x7a597eaf, 0x30a9ec50, + 0x74d4845d, 0xd003d0a1, 0xfa42ffc7, 0xf1f09ee8, 0x9efe68f3, 0x169bd098, + 0xbd810f4b, 0xeca293a7, 0xb3f678e8, 0x48273762, 0xc7da333e, 0x595d797a, + 0x9e1d2e79, 0xf25dba8f, 0x62b9f058, 0x0fccdc4f, 0x80e01d60, 0x91cc7d02, + 0x83a4ddf1, 0xc0dbe006, 0xf288214a, 0x63d621e6, 0xaa1ef9c0, 0xc9fca835, + 0x8f9ee639, 0xe6fd087e, 0x3d270dd4, 0xbf28c3e4, 0x38f3ef48, 0xffcf3d44, + 0x5c9ebcb3, 0xaee6bff4, 0xd1fc6836, 0x39e3a224, 0x23ecfe4e, 0x09303be8, + 0x4d4aedc7, 0x76f94d1a, 0xfced7f55, 0xe3b43aca, 0x91abdf6a, 0xee78b2e3, + 0xf7851dca, 0x83b71251, 0x131ef0c2, 0x6f80bc39, 0x6aebac1d, 0xd3e088db, + 0x2954e831, 0x8e5d267d, 0xef52393e, 0x3b38d37a, 0x955f6318, 0x3f7c1479, + 0x7c153ac8, 0x0e8b1e7e, 0xffdc7d8b, 0x910e6dd6, 0x2f1dacbd, 0xec8ca7a7, + 0x81269cb0, 0x4de5deec, 0x2af9ba25, 0xa3fb9bfb, 0xa6efec7d, 0xf2de3483, + 0xfedc8396, 0x3b23aa6e, 0xf70b797e, 0xa43ec047, 0xc80463f3, 0x15cbb268, + 0x7983d33f, 0xb79815a2, 0xbd21ede4, 0xf3d5cf0b, 0x78d235fe, 0xf21ca9f1, + 0xc0ff7913, 0xa7e8b5c4, 0xa85afd86, 0xbab5fb47, 0x9576c2ba, 0x6c281b5f, + 0x5b5f91bf, 0x05385f53, 0x8fe05afd, 0xcdc15245, 0xe4b663f9, 0x797fa1ba, + 0x41ade4c4, 0x02e2533e, 0x6abffdda, 0xfd202572, 0xbdfb253d, 0x23cf57d3, + 0xfc3cde7b, 0xa37990da, 0x7df2de51, 0x76e24c7f, 0x7be88a4b, 0x3eebc70c, + 0xcf172d74, 0x7fb4d4cb, 0xbcf911ba, 0x1ec3ce4d, 0x5d9157f7, 0x13dfeca3, + 0xa777b712, 0xa077688f, 0xc14f7ffd, 0xcfe81cef, 0xbcf3d65c, 0x4922a5cf, + 0x18f66f65, 0xd7027aee, 0x1e8094ad, 0xf16ee511, 0x82938e84, 0x8ffcbe23, + 0x808f77c8, 0x7b5d9df2, 0x5bd70d3b, 0x81d872d3, 0x7e84bef8, 0x5bc9c610, + 0x8f30d3da, 0x77f9a2b8, 0x9e7bf40e, 0x7b5db897, 0x40e9df59, 0x1ef96ebf, + 0x5fc9dbb0, 0x003da50a, 0x32d4ba78, 0x3e69f0bf, 0xbf5a298d, 0x85f57fe1, + 0x76edbb11, 0xeb282053, 0x284e253b, 0xefa1875c, 0x663d116c, 0xedfb5f47, + 0x4dacd1f2, 0xcc0fb815, 0x0f861ee0, 0xec83acf5, 0x09962539, 0x21cf0a92, + 0xbf2b901d, 0xefbde96e, 0xe7162236, 0xda0251ba, 0x0c14be3d, 0x8db69592, + 0x9188375b, 0x73d950be, 0x12ef7b5a, 0x1b77dd73, 0x7aa3b9ca, 0xd6b37686, + 0xfdd163fe, 0x9f7fe387, 0xd6bcbc25, 0xfdc56d92, 0x59d320da, 0x54ef4b4d, + 0x166a97e4, 0x6f7e0efa, 0x3a22dd55, 0x7246ec43, 0xf85bdd77, 0x9b7753fd, + 0xd8f485c1, 0x34d876dd, 0x22adeb16, 0x4e6a99c5, 0x3a428f14, 0x2866d2ba, + 0xbcd7bc47, 0xf903b1f9, 0x57cfd15b, 0xde7a44da, 0x9e9676dd, 0x695ee32b, + 0x7a851e4d, 0xfdc759a5, 0x9f238ebc, 0x7fdf915b, 0x326aed7d, 0x7eb297f9, + 0xaaa7618d, 0xddad4eec, 0x6e19e53a, 0xb5494e47, 0xec579c93, 0xf8fa3ecb, + 0x67675b14, 0x6b1f425f, 0x4919f0f4, 0x616ef3b6, 0xd8af31e3, 0x19792d7a, + 0x9b7765f2, 0xe286b9d5, 0xe88edc1e, 0xb9f4f8ee, 0xb8fcf819, 0xee9c7148, + 0xf1d1226b, 0x86cb03a1, 0xf1a2d976, 0xf5fb4f5c, 0x5f3fc0d9, 0x3ffd0fd9, + 0x07716c3b, 0xf77a7d70, 0xd63daf28, 0x78e504be, 0x97432841, 0x4320658e, + 0xec35f457, 0xe27d93c4, 0x7f91d7f7, 0xa67a9857, 0xddcd18a2, 0xfe425a7a, + 0x057920df, 0x2687e923, 0x8075f22b, 0x73c20e95, 0x561655cc, 0x53d4f48a, + 0xa0db9cc7, 0x9d51cf75, 0x30fb04ce, 0x1ba64761, 0xf955edb7, 0xa692f35c, + 0x4a332906, 0xbf912c5e, 0x0860bb3b, 0x7a8a490c, 0xcb91a4fe, 0x97870bab, + 0xeef248be, 0x161b237d, 0x362dbf43, 0x5bb57d72, 0x85d8cc0a, 0xe8e8cefd, + 0x238ec1fb, 0xf3c11c6f, 0xba4e4b10, 0x28bea1c6, 0x6ffa7231, 0x3d6afe3d, + 0x3d690b9e, 0x76f478c5, 0x83a8a57b, 0x1733f779, 0xabbd3f8f, 0x1c23ff23, + 0x649e63b7, 0x461de75c, 0x1ff6672e, 0xc74795d5, 0xe7cbf605, 0x1a356e1c, + 0x4661fc68, 0x8ed7ca91, 0x23cf2696, 0x19e5f3be, 0x75ceef91, 0x915c3bd5, + 0xef629578, 0xb5f77a4c, 0xcfe06319, 0x4e749749, 0xbbd76edc, 0xaf5c44db, + 0x896302eb, 0x07fb5f42, 0xf88f1bc6, 0x7fdbc657, 0x70078f89, 0x54be421c, + 0xf41a0ff0, 0xbea1a347, 0x849f53bf, 0xf82813df, 0xcca1d657, 0x9e626aef, + 0x8eb11b46, 0xc41bb5e7, 0x8f52314d, 0x54ef91f4, 0x7449cef8, 0x29e486f9, + 0x1810f4e5, 0x870bf582, 0xec57642d, 0x4b11f596, 0xf88a1caf, 0xbe69f653, + 0x0513eb91, 0xcff3789e, 0xca54e191, 0xafd74b2f, 0xa2015c1a, 0xc5023d9b, + 0x90815c19, 0xfb053b29, 0xe739d365, 0x37d8de48, 0xbd87f707, 0xd6ffa6ab, + 0x8ace9d2e, 0x214df1f2, 0xfde0d291, 0x74c34fb4, 0xfa226fa6, 0x88c93d6b, + 0x7cee978f, 0x58cdc798, 0x728e9068, 0xc84181c8, 0x9c3fc8b7, 0x0503437f, + 0x35b52728, 0xf8441dae, 0xaf90390d, 0xbe027822, 0x41b6b2c1, 0xb25d7a42, + 0xe58b978a, 0x6c9647ef, 0x2e7f11f1, 0x15395ada, 0x98d5a7ed, 0x28bd40f4, + 0x59d32bd3, 0x4ebcf032, 0x85df6caf, 0xdd3897e1, 0xd4d96c5e, 0x7d02f38e, + 0x63e233fd, 0xcfb3eb72, 0xbd0ab823, 0xa06edc5e, 0xde90aa71, 0xad74f8a3, + 0xde7bafbc, 0x693ef4e5, 0x7bf4a1bb, 0x0149eeb0, 0xec38c4e6, 0x443bedfe, + 0x91fbdf94, 0x9f39339e, 0x70be9ea3, 0x63eb69f8, 0xeb4ecfa8, 0x777bc618, + 0x39aaac4b, 0x1a3a2f8a, 0xeff1575f, 0x33759dd2, 0x95dcae28, 0xa66ba024, + 0xf782adf0, 0x1a7b92dd, 0x34b7fff1, 0xdfc65ffc, 0x81ff87df, 0xfe649b7e, + 0xfc0e54df, 0xb7128f0f, 0xce380a27, 0x79f6296e, 0xfd8d57a1, 0x5710b73b, + 0x23ef1eae, 0x72355f57, 0x0d91dbff, 0x73df57f3, 0x30effc95, 0x6cdd327c, + 0x26e8532a, 0x7b71f053, 0xf8839753, 0x3d22bc02, 0xf289bd93, 0xb82b24b6, + 0x8f45884d, 0x967c946b, 0x72236f8a, 0x5f5fe14d, 0x5853c21b, 0xed16bb56, + 0x008ae4e4, 0xc145e9d1, 0xf4093437, 0xe7e445da, 0x67e17218, 0x333e5e32, + 0x1be754f8, 0x32c1c2fb, 0xc0abae90, 0x69f3a2e3, 0xee27055b, 0xdaeed28f, + 0xf782fdca, 0x9e573e65, 0xf915ffbf, 0x53f78c3e, 0xeface27d, 0x933eb91b, + 0xdcceb04c, 0x4c67d720, 0x60be2528, 0xc819e9ba, 0x8f404b6f, 0x8f4a2f7d, + 0x1034345d, 0x38782abd, 0x67fbd32b, 0xcfdd7c89, 0xc41e70c9, 0x5be12998, + 0x7a0947ce, 0x5af9c0bd, 0x8bbf3814, 0xc3c5fe38, 0xdd11a793, 0xee9b13df, + 0x246aed97, 0x772c4cfa, 0xb3b9438e, 0x2736ef49, 0x8f258e8e, 0xec765483, + 0x49f909f8, 0xf7c8c748, 0x0aa0f8f1, 0xa0c580f9, 0x7fd020ff, 0x7429fed4, + 0x1d717400, 0xd73ca5f1, 0x379285d2, 0x5bb2f053, 0x669b7793, 0x601a78e2, + 0x25def2e2, 0xfa78a9cb, 0xf3ef2be5, 0x2bf87dbb, 0xe6a054cd, 0x456fdc2f, + 0x13717c4e, 0xe2679b3e, 0xfa644fed, 0x780ede4e, 0xe4a0627a, 0xeb720b5a, + 0xe766d809, 0xa63e48f8, 0x595f9e49, 0xa09348c7, 0xf368dbca, 0x6f830629, + 0x9f0a2984, 0x8d73f798, 0x334bd08e, 0xd81cfce3, 0x43cf946e, 0x5f765538, + 0xc6912981, 0x40c1ea77, 0x967fd405, 0x0361d959, 0x0ceeeeb8, 0xe1718c54, + 0x5981db77, 0xbae264f7, 0x853e829c, 0x53ace5d6, 0xdf20ce8e, 0x7c50b71d, + 0x3ddb3f24, 0x974cfc8a, 0xf7c71f3b, 0xeca4fbc8, 0x6b75bc67, 0xfdbc5cf5, + 0x21e3279c, 0xcad76e55, 0x2e26418f, 0xf9657a37, 0xf83fe5a1, 0x526f9317, + 0x3b242fb7, 0x6d8c9d90, 0x326fde07, 0xff5179f0, 0x00d4bf40, 0x23ddfeff, + 0xdcec27ef, 0xc343c41c, 0xa39d2376, 0x31d7f850, 0xf18e9bcb, 0xe48a4713, + 0xaeb8c176, 0x7e1a6c59, 0xe8f2efbf, 0xd651bfc8, 0x26e1ff5f, 0x7ea26fba, + 0x7da19187, 0x57ef209f, 0x0c162cc2, 0xbaf9f109, 0xb1e80763, 0xd3fe2894, + 0xee89eb07, 0x5103bf80, 0xd93437fc, 0x2d806e97, 0xdbfac1fe, 0xc0b74cca, + 0x8ccc993c, 0xa82aea16, 0x347c006f, 0x96047924, 0xb675f548, 0x0fe3f181, + 0x2e4d303f, 0xbf04f3c3, 0x6fbe7a32, 0xc438a54a, 0x1c2cb00f, 0x28b22b50, + 0x1d99bdbe, 0xb1f955f3, 0xb0738e46, 0x69469036, 0x9ce2f8aa, 0x2f8a2e9d, + 0x507c8d3e, 0x79fe719d, 0x8da6ae1c, 0x078beb9f, 0x678c8a47, 0x17c4e790, + 0x115ade29, 0xcf857ffd, 0xc925379e, 0x3011ebfb, 0x1dd0aefe, 0x93da29f2, + 0xe31d7e4a, 0x2f8a762e, 0xb0ee8907, 0xc23e309e, 0x742a1b7f, 0x61e2b1e5, + 0xafb64cbb, 0xf23487a7, 0xb17db589, 0x4bd031f7, 0x48b7f835, 0x29976af2, + 0x54d81eca, 0xc78d2671, 0x439d19cd, 0xe39e447e, 0xffee35c5, 0xe1f28e18, + 0x947efcb7, 0x80294671, 0xfdc0aae7, 0xe4d33975, 0xda9d90f1, 0xfc1d9084, + 0xd1cf9add, 0xf37f0173, 0x2f951d73, 0x3cb7b3fe, 0x56d9ed13, 0x032c1b9d, + 0x5c93ebcc, 0x41650f70, 0x9373d013, 0x2a9b9f85, 0x9079b769, 0x1305bbfe, + 0x13e99b9d, 0x19ea2f8f, 0xd7da0bb2, 0x411f01b6, 0xb184bbb5, 0xef57844e, + 0x0ad0f3a6, 0xd89ec77e, 0x63df4794, 0x37dc1be9, 0xcbc55b8a, 0xb6af16df, + 0x894adc50, 0xf4f71593, 0xb5649d10, 0x61f8ea65, 0x5e8f3e29, 0xd792af5e, + 0xbef1926d, 0x226be8fb, 0xb2c2b1ea, 0xef68b586, 0xef7d1867, 0x2e4ddd23, + 0x1339db56, 0x3b76da84, 0x4634d7d2, 0x1fc2827e, 0x20ec5dc9, 0x4f12a986, + 0xcfd07976, 0x73c17c9a, 0x04a9fd10, 0x77f8132f, 0x24f3e192, 0x58ff70e7, + 0x07b8478a, 0x13fc29c6, 0xe328bc23, 0x2a5a3eec, 0xd2919da0, 0x46b82659, + 0x2defa5f7, 0xe04e77e8, 0x5f701ee7, 0xe8687f15, 0x6196462f, 0x2fe9487c, + 0xbd5cb99a, 0x429be7cd, 0xafa34fa1, 0x349de717, 0xa98ed83b, 0x81558997, + 0x84f10c76, 0xd184b3d7, 0x02ba8378, 0x27818eb4, 0x9658257d, 0xf7048948, + 0x3a210be4, 0x96a0312f, 0x5b9231d1, 0xfb25df3a, 0x4eda96e1, 0xf771f701, + 0xef0443d1, 0x5e0ecee0, 0x9af57cca, 0xb814ffac, 0xa27f644a, 0xd5c38e44, + 0x8e9f9e5f, 0xecd181fe, 0xa338c12b, 0x12fa8eb2, 0xbf9e3a5f, 0x3ce782dc, + 0xe73fc426, 0x14966691, 0x8cc1373f, 0xaeecee7e, 0x5a7b4823, 0xf8ed39bf, + 0xb48fda19, 0xdd1ddcd5, 0x80a57c72, 0xc1e5b5f4, 0x22b37ed8, 0x71c8b62f, + 0x14f3a8c4, 0x7ad1cd83, 0x9ac932b9, 0xc28f2515, 0x9e722672, 0x9e7cb762, + 0x6f7aa6c2, 0xa46613cc, 0x27834ea7, 0xdf2b9f07, 0xdf2abce1, 0x71f8a01b, + 0x961ebe0a, 0x9e68d3f7, 0x1086e749, 0xe3a04e4f, 0xbfb1cd57, 0xd6685987, + 0xd3977ac9, 0xf4e4eb0b, 0xb688eb82, 0xb999a633, 0xe3cdbd5e, 0x74e7a29b, + 0x9c788452, 0x476c1454, 0x1e589dba, 0xbffa4768, 0x5274c985, 0x4b44e9ce, + 0x939bf7ef, 0xa1e93a64, 0xe0260a7b, 0xe43145f7, 0xdb998563, 0xa59d2977, + 0x0fc03f44, 0x857ce177, 0x03456a83, 0x339cd0a5, 0xf0f8ef50, 0x9e7822f2, + 0x4769e45f, 0xbc7a737a, 0xa8db8e22, 0xc9ba7277, 0xb8c49ef4, 0xe4aa7d77, + 0x38d02b5e, 0xe0c736df, 0xa7e416ab, 0x4a7e11d1, 0x5a47e391, 0xc3229cba, + 0x1cf193e5, 0x43df1e7f, 0xa74a4f38, 0x33f783ce, 0x4c25b9e0, 0x055c4e46, + 0x96f912fa, 0xd2f9d275, 0x09672aa4, 0xe5a0ddf2, 0xf9f7016e, 0x016fbd25, + 0x3c76b3ee, 0x350c9f45, 0xbffe8879, 0x6268deb2, 0xf2ff8d26, 0xb5db99b0, + 0x7e512b1b, 0x8499f2bf, 0xf0a5d5f2, 0xd6f1d1e5, 0xf3745179, 0xf83a5f74, + 0xa07458a7, 0x3a5a7f95, 0xb50bc888, 0xadbc03fc, 0xedc3fbe5, 0x55ce94dc, + 0x6a1b9722, 0x7f6f1779, 0x0d0dc8fa, 0x3de98f1e, 0x097ae0cf, 0xf39105e9, + 0x74f4f1db, 0xae1ff9a3, 0x31cd1ba7, 0xd4ceb4f4, 0x9f3c1bf3, 0x744da2bb, + 0x5f225c61, 0xf6ba8f3e, 0x4f3a24f1, 0xe09362f0, 0xd1439746, 0x502244d3, + 0x6127b2bf, 0x4a15bb2c, 0x6ae78078, 0xb2250302, 0x08c759cf, 0x24d633ca, + 0x1bac70ca, 0xdbb7fa41, 0x51e600a9, 0x256063eb, 0x91d3fa01, 0x684b181d, + 0xf310783a, 0x988b6b2c, 0xb77000cf, 0x80f3f1b7, 0x485bd62f, 0x7e3eef9f, + 0x400f37f5, 0x1d71e73d, 0x0e047f1d, 0x4ab673a6, 0x03b145de, 0xe8590e3a, + 0xb32f703c, 0x7754d1b8, 0xf8790d8b, 0x21fbec02, 0xe8d983c4, 0xe2281fcb, + 0x77aec439, 0xf1eca38a, 0xccbfd6de, 0xe48ae439, 0x7d0e9a97, 0xdf6d185e, + 0x14a9f929, 0x3996f7d1, 0x963fdfca, 0x77cb9677, 0x055fb9cd, 0x9c5e309e, + 0x5da27f1c, 0x2375f04f, 0x48bf687c, 0x10fb861e, 0xe3d648f8, 0xfb94de32, + 0x0adbba0f, 0xbe80fa4e, 0x98393c5e, 0x7b5be1c7, 0xef7768cd, 0x214ef932, + 0xf4b7899d, 0xf6a9f9d0, 0xe811deb6, 0xf9fc834f, 0x1ef79f08, 0x9d149b3f, + 0xeb12feff, 0x3f5a24fb, 0x729f5bc4, 0x1f4b5e3e, 0xda167dda, 0x184dfe0e, + 0x50c07c4b, 0xb086054e, 0xf567fa20, 0x17adc663, 0x31672371, 0x341dc517, + 0x999fb479, 0x8e65ffbc, 0x4c679fe2, 0xde21bfde, 0x4efc1e71, 0x05f9d603, + 0x989ec7d6, 0xdb478f9f, 0xf53ac2be, 0x18fb9896, 0x215afda2, 0xe60567af, + 0x537cf0fd, 0x3852e18b, 0xef231ddf, 0x8091fb07, 0xdd4a05e3, 0x9fb87d27, + 0x6bdcd81f, 0x4efa1f11, 0x0091da27, 0xb3b6227f, 0x97ba4aa2, 0x50f060c7, + 0x3ad5f47e, 0x5bbd7e7e, 0x1e31b8b0, 0x6491dcd6, 0x33f87941, 0xfb1d2f93, + 0x9d5dd48f, 0x09fa7183, 0x3cdd5e9d, 0x41be53d2, 0xe753b216, 0x8e09eaf7, + 0xdfda315a, 0xcfeb12fe, 0xe7dcc4b1, 0xc790fb3e, 0xa1f7c5d7, 0xf462e7df, + 0x3e9c7bfc, 0x45d651f9, 0xfb83f6f1, 0x3cc5c93e, 0x4f81f552, 0x7ead3fc8, + 0x5b9b48c3, 0x0488c6f6, 0x252be3a4, 0x4b89edb1, 0x1eb75afe, 0x967199ec, + 0xcb9b922c, 0x23dd2759, 0x61e9a2b0, 0x5e4a3eb7, 0x71d3f62a, 0x8e056743, + 0x6440bc7f, 0xbd774075, 0x580389ee, 0x94ac390c, 0x097b45bf, 0xfd1f7f60, + 0x9f9bd4d2, 0x9de6d283, 0x338fb4fb, 0x42a11c53, 0xb3cc8763, 0x88f73d70, + 0x8fbc325c, 0xbcbce005, 0xe0e74ed7, 0xcf7f8f2e, 0x5c4b1f81, 0x7e5df96e, + 0xb0ffcf00, 0xbf3047ce, 0x8d8bf816, 0x718aa8fc, 0xd9d7e5ef, 0x3b76fc23, + 0xdbb0418f, 0x70e13f5f, 0xe68aff41, 0x144094f6, 0xa1e7b4fe, 0xc7d7911e, + 0x6e745df4, 0x98bfed84, 0x563ef786, 0x829c3bec, 0xec37fdeb, 0xaedfc318, + 0xf44d5d58, 0x9f22d533, 0x1960caa3, 0x8bfa0f28, 0x0573ed07, 0x5dc7c70f, + 0xf77a821c, 0xd23b1c4a, 0x75ebf72f, 0xf6801a4f, 0xca14854d, 0x55bf1589, + 0xbc2d2bfc, 0x3b373b37, 0x58f7e243, 0xb6af9f6a, 0xebdf3d70, 0xf000b336, + 0x068d23e9, 0xc4eeaefa, 0xcacc3fb5, 0x64f8fd87, 0x06b9c1ab, 0x85eaadf8, + 0x309bc1f6, 0x48ce395e, 0x5c4f97f1, 0xcba41ca1, 0xf3f02fc5, 0x7d6c9fb8, + 0xc8f30d24, 0xb5f409ff, 0xdc58e01c, 0x55e7a068, 0xe7a7df8d, 0x5bba6517, + 0xe52a42fc, 0x3c744f97, 0xaceb869d, 0xdf93fbfa, 0x966ffe41, 0x41c6a39c, + 0xa0977cb9, 0x74b7773a, 0x575559bb, 0xbacad2f2, 0x8f391099, 0x7e7802e7, + 0xe79af969, 0x89f57780, 0xc2d2fe5b, 0xdd6f8bed, 0x2eaeeb07, 0xaefb25e8, + 0x8c8588fd, 0x44db5fa8, 0x71a1dfd2, 0xadd6f5ff, 0x77f29f50, 0xd31f9bbd, + 0xb239274d, 0xece5c4c8, 0x70fa7d94, 0xff719cbe, 0x615776dd, 0x08797cfc, + 0xdbd200e4, 0xe18a9f94, 0x79f479bc, 0x5cde6d54, 0xf36b8fc9, 0x029c78e6, + 0xf2cdf1e5, 0x1c3f0ae6, 0x49cf84b3, 0x1fb7dd12, 0x45f279e1, 0x2f6e45c7, + 0xfc4e44dd, 0xe3d6e116, 0x107b1efe, 0x6427dde3, 0xf6b89c6c, 0xafbc3ac9, + 0x012293e1, 0x93ec2033, 0x58f2c66b, 0x2287707c, 0x659cf02f, 0xef5f645e, + 0xd7092f71, 0x5dbe0d91, 0x1ceab0f4, 0xd5e5ff68, 0x49f0f98d, 0x419eff0b, + 0xfcb4cf2b, 0x67928ff2, 0x0f0ee315, 0x7ca9d809, 0xcd4bcb19, 0xe568ae5c, + 0x14a7581b, 0xe4e55a87, 0xa5c0a2f4, 0x5fc57785, 0x3f3058b3, 0xf5177e1a, + 0x94efa15b, 0xf8acbe50, 0x260b2e6b, 0x50fea37f, 0x3f8635b2, 0xf095fa04, + 0x07d42815, 0xfd408fd1, 0xdb46fd8f, 0x0025c95c, 0x96673ad2, 0x2772e515, + 0x416b7fe8, 0x6a313e24, 0xe50e8357, 0x376fd845, 0xc577fda8, 0x72b2c95f, + 0x795a31ba, 0xddfc98fd, 0x5df3bc4f, 0x3c4af8ca, 0xf184bea4, 0xb91273ef, + 0x839ca6fd, 0x3967eb5c, 0x933e3df8, 0xd26bc3bf, 0xc8f0eff1, 0xfcf5c4a7, + 0x83fdc8d8, 0x5c5574bc, 0x29bf09f0, 0x792def07, 0xf7a4efd2, 0x53a7f29f, + 0x8bbf23f9, 0x79fc67ca, 0x135efc39, 0xc7c8fe46, 0xd18d2c87, 0xe49b04e7, + 0xb093cdbc, 0xd062d7de, 0xe55623e1, 0xf497a03c, 0xd8d2c2db, 0x567bfdf2, + 0xe4a5e13d, 0xa087fbf9, 0xc1f1f1dd, 0x097dd1ef, 0x83e26b1f, 0x6e6f250b, + 0x13f37d2c, 0xc9379f99, 0x32c7e5fa, 0xfd900d7f, 0x9e729047, 0x4f78d1e6, + 0xff773f30, 0xc31dfcac, 0xa9abfd4f, 0xf3cad3bc, 0x8ff76923, 0xf0073b7f, + 0x3f036e75, 0xa4ce749f, 0x6cf3bf23, 0x85bcadad, 0xfd8ef0e0, 0xde76511f, + 0xf1dc329d, 0xfd6355d6, 0x057e726a, 0xdea072eb, 0x876fd30a, 0x5c3e1e3a, + 0xfa432df4, 0x695d66eb, 0xe846afd8, 0x2315ddcc, 0x79209b8f, 0xff84ac6b, + 0x5f28219e, 0xed02fd95, 0xfefa2a31, 0xe72b228c, 0x7ce38fcb, 0xa65ab6ff, + 0xcf25dbdb, 0xfa9e3e6a, 0x195fc37e, 0xf2b43f3d, 0xb4ffe678, 0x8c02f9ca, + 0xce4894df, 0xdb9d7c70, 0xd635dedb, 0x78997118, 0x8e16bf7e, 0x9e9c6c5b, + 0xa500f1b4, 0xcf01e254, 0x65044da0, 0x7049d5a6, 0x1803e36b, 0x07158d27, + 0x8f2b4ff8, 0x3c7ba61f, 0x9f15d5a2, 0xcef8272f, 0x6c9b7dd0, 0x7bf3a336, + 0x0e9b8a03, 0x60643c62, 0xd90eb059, 0xcb513ea5, 0xc63301a7, 0xba7cb249, + 0xa4dbcc34, 0xa33f0275, 0x6a9781bd, 0xd69d22a5, 0x4f5d21d6, 0xf168e9f0, + 0x412c3a13, 0x54e67141, 0x660266e7, 0x0bfeef39, 0xda82f3c2, 0x1db718b5, + 0x797fbcb4, 0x9f7936f7, 0x84d9bc95, 0xc3c206ed, 0xa63fed84, 0xed84d6fc, + 0x2885eb77, 0x35693efe, 0x878bff50, 0xff250e97, 0xaa39ce38, 0x26dc794e, + 0xfc417bc4, 0xadc710f3, 0x8879f8df, 0xb8a8d6e3, 0xab8af54a, 0x5a77c724, + 0x39f8feb9, 0x9f0169e6, 0xe4a05f3f, 0xfe291b69, 0x9a6a5bb6, 0x40887986, + 0x43ce8eb5, 0x0bdcf386, 0xf08f79f8, 0x86ef98fb, 0xe2af3fe7, 0xc181eef9, + 0xf6df2967, 0x03e79999, 0x6461db3f, 0xf25d2798, 0xefe51376, 0xb1d72cb6, + 0xc364f758, 0x9cf9064c, 0xefcf018e, 0x7ca3fee0, 0x081df653, 0x08fdc24b, + 0xf9b5c3e7, 0x8bae193f, 0xe9723e72, 0x4869e6ce, 0x93cb1927, 0x563fbc04, + 0xeaebeb81, 0xbf506f91, 0xe5f7975e, 0x6f55fa66, 0xb55fa18b, 0xe0d3b57a, + 0x6f52da31, 0x641b5fae, 0x2ab5eafa, 0x78e406e7, 0x6247e637, 0xd633cbec, + 0x34ce713e, 0x738857db, 0x3149adfa, 0xf7ca9ce3, 0x6c490d9e, 0xfc18ccee, + 0x37cc98f0, 0x743dcdba, 0x4da5230e, 0x4a972988, 0x17c94924, 0xc545b08d, + 0x35f2b5c7, 0xd8dd7e06, 0xd0aec47f, 0x3e35ec21, 0x668ac731, 0x9c73e000, + 0xf2719f0a, 0x9533bf0c, 0xe4a27d90, 0xd49a2e15, 0x6c77dbf6, 0x6dcf3f4a, + 0xc4b78fb8, 0x6c53db91, 0x297f0282, 0xc5594bf6, 0x2572f154, 0x1b529e4e, + 0xaffbf010, 0x3f230f14, 0xafb26862, 0x7afd00ce, 0x36f73126, 0xe83c27a8, + 0x9779412c, 0x883ee554, 0xcbfadda1, 0x0fcaf7f2, 0x395efa33, 0x65f5ef9c, + 0x7883bd91, 0x4f0efe8f, 0xfaca0fd1, 0x6bdd6f40, 0xb2cd70e3, 0x7d6f40dd, + 0xcf317c83, 0x58be3fd6, 0xf769708c, 0x81ef1b2d, 0x7fd98d4a, 0xb0feac45, + 0xd9fdd5cf, 0xbc720de7, 0xa4f9bfbf, 0xf5f0bd46, 0xf17de5e2, 0xbc2c44f2, + 0xe5d0a86c, 0x009479e1, 0xe963b8b3, 0x7fb62d9d, 0x8b7edc78, 0x9edc462d, + 0xfebf24dd, 0x49773fe2, 0xe2560f18, 0x507b61cf, 0x9e575793, 0xf909b757, + 0xb49597e8, 0xb7fb235f, 0x64e7e0fb, 0x8fcdf6ff, 0x025779f3, 0xdc7f2279, + 0xbf6f9f25, 0xf7fb95ba, 0xa4fd7322, 0x39a8e018, 0x6841606a, 0x606f8abf, + 0x882116fb, 0x3d5f0bf7, 0x8bea853a, 0x192c09f7, 0xe9e02409, 0x160cefc4, + 0x425e3e30, 0x8f754e91, 0x7d47a275, 0x7972784f, 0xea9eaa92, 0x3e13df55, + 0xaa967660, 0xa46fa07d, 0xd5507daa, 0x96fd5578, 0xe13df55a, 0x457f4143, + 0xd30333d7, 0xd7b3fd55, 0x0faaabdf, 0x13df506b, 0xcbadf8ae, 0xdf0cf5e4, + 0x2f7d4f32, 0x61084877, 0xbca163be, 0x38e40bdd, 0x52e088c5, 0xc4cb38d5, + 0xbbf0470d, 0x57de9b8a, 0x7448dad4, 0x68afbdaa, 0x7d754ed9, 0x46fb89ec, + 0x5e0cf3f1, 0xc675373a, 0xdc5f8ea6, 0xc3035f74, 0x1abed6bf, 0x6afbd5d3, + 0x886e5976, 0x7a9e6b37, 0x6f7c999f, 0x766f168c, 0xbfff7ab7, 0xed19bc69, + 0x0c193c6a, 0xe31d8b3e, 0x44abad80, 0x5cb2defa, 0x4bee4e7d, 0xed93ddc4, + 0xcaeee231, 0xcf376abd, 0x0dffb4a7, 0xd04664f3, 0x173c0634, 0x8536e455, + 0x48e627f3, 0xaf2b5d9c, 0x75e41294, 0x2af29d8e, 0x5ad3bc91, 0xff21df86, + 0x2b708bde, 0xf7588979, 0x05ce6880, 0xbe71c68e, 0x4d0afdea, 0xd240e7f8, + 0xae76f983, 0x51ec0b07, 0x8739507a, 0x78c1e8a2, 0x897928e3, 0x4870a578, + 0x0f44b8a4, 0xc86257e6, 0xbfdb6ff1, 0x7be93ea6, 0xf6dbf38e, 0xe0bf2882, + 0x5047bdfb, 0xefde039e, 0xedd9f5c5, 0x888527a0, 0xd589fc9e, 0xf3d3fc41, + 0x3c38311b, 0x48be7233, 0xe1689fc9, 0x0f7cd62d, 0x87b9a6d9, 0xb73c7eb4, + 0xb9dae63b, 0xdf2c3d5e, 0xd7235143, 0x7a76346b, 0x8fee7acd, 0x6d15bde2, + 0x8d5ff651, 0xe7fd4edd, 0x106a4be8, 0xf70b46ee, 0x8105eaab, 0xa67d78f4, + 0x6e3ef340, 0x71f6a52a, 0x5c6a92f6, 0xacb930f7, 0x2a5e58c1, 0xed443bdd, + 0x5efb1892, 0x6e765582, 0x7896cf2f, 0xddfd2fff, 0x0ee60ad4, 0x9bbe44a5, + 0xd3be7162, 0x3d83c6d7, 0x140ece79, 0x3bf55f8b, 0x9a1fc42a, 0x3f1d0ade, + 0x43e70f63, 0xfaf9fbe8, 0x66e7aecc, 0x109ebee0, 0xdb1e78dd, 0x1d602a75, + 0x57c7829b, 0xa02256f1, 0x8d6cad93, 0x038bea19, 0x18f78a2e, 0x8fb25fc0, + 0xcbddf08f, 0xc7c24cf6, 0xd3219398, 0x789f6858, 0xe3107bca, 0x58b3b9c3, + 0x06ed8a12, 0x7f0530d6, 0x55b0291f, 0x5ab31bce, 0x19abfdfa, 0xe8a52b25, + 0x5ba94073, 0xe2f3a61f, 0xf87579ca, 0x28fc4167, 0x9e47dff7, 0x4338f3f3, + 0xe32f654d, 0x98e5297e, 0xc578ec60, 0xccbbf96c, 0x5ddef587, 0x5a63dfb8, + 0xbddee8ba, 0x5b1c8ac5, 0x9defa3a0, 0xe1f793ef, 0x0f3cadbe, 0xbf5daecc, + 0xce46162e, 0x0cf8c1fd, 0x2cf173f9, 0xb3bbdd3b, 0xbe932db8, 0x815e668b, + 0x6d351be2, 0xbf497b6f, 0x44e0984c, 0x01f3d37f, 0x4b7ef013, 0x039701c4, + 0x952efbea, 0x95efd37b, 0xa77ca7d7, 0x8372f20a, 0x78bbf015, 0x81a1dd6b, + 0x2f7bde30, 0xa18fba31, 0xf240acf0, 0x37168981, 0xcb85edda, 0x05cfba04, + 0xbdd1f40f, 0x6d862314, 0x7e3b8e8b, 0xb78bcb2a, 0xe5a078fe, 0x9c297404, + 0x2a48f952, 0xfda768ec, 0x5dfc54c2, 0x95fdc2a8, 0xa338648f, 0x7b2a9bea, + 0xde11bb07, 0x80cb530b, 0xe760fe4e, 0x85d74cf0, 0xd9bbfcf4, 0x543fca4e, + 0xd20f24d8, 0x9d2d8569, 0x80ae37ee, 0xf400bdad, 0xdfa3fd35, 0x9f2e51eb, + 0x05f7cbb2, 0x5c5cb2e4, 0x77c3b267, 0x2accf89e, 0xaf10339f, 0x0fb68d8d, + 0xe539f4a3, 0xacdbba47, 0xf9586994, 0x3fe53666, 0xfbb4f795, 0xdf9f9cfa, + 0xf0ec9873, 0x57fdc79c, 0xfade81fa, 0x93ddeb1c, 0x1db97f3f, 0xfc52bdc6, + 0x17082197, 0x677e8fe0, 0x4ebfb941, 0x296dc719, 0x3f2762b9, 0x3f717986, + 0xf9e3936e, 0xbb6d9d93, 0xebb7dd71, 0x0e516b42, 0xa9fef9be, 0x28671c64, + 0x3eb8e078, 0xf5d573f8, 0x4570bee4, 0xbf7abee4, 0xf9f0a70b, 0xef2bbf0b, + 0x8bc79b9b, 0x500df7bb, 0x0eed8bc5, 0xbfb86fbe, 0xc0937fd4, 0xcfd9f1ef, + 0x937c564b, 0x9055fef7, 0x05824f7f, 0xe577e844, 0xc00fde4d, 0x66a87f21, + 0x13a270ff, 0xb3cb839f, 0x51e7acc9, 0xb6e4e75c, 0x87efa77f, 0xf2792b27, + 0xb93cea0b, 0xe2a59f0f, 0xf43d23b5, 0xb5f7701d, 0x63796fde, 0x43a95bf0, + 0xfbf0fbc9, 0x837ec3f0, 0xf87e1f7c, 0xec5342bc, 0x7197f0fb, 0x89f120ca, + 0xc52f0fdf, 0xe12fe03a, 0xe907f9ef, 0xc166c1fc, 0xb04c798d, 0xcfef5483, + 0x87ded3c8, 0xf17fefcf, 0xe3df93c9, 0xc91f33ee, 0x1e194adf, 0x5dff1b5f, + 0xcf3c0e82, 0xdeea7803, 0x51377fc0, 0x777fcf7b, 0x05b7e739, 0x4ba085eb, + 0x553bfba0, 0xd6650bed, 0x6776085e, 0x3cec9328, 0x3dc477cd, 0x5c5f6c5e, + 0x041befcc, 0xded34fbb, 0x754fe0a0, 0xf961ec4f, 0xfe1671f7, 0xf237d658, + 0x64f32fbd, 0x590f31f8, 0xaf591692, 0xf9147fa2, 0xe16050b9, 0x1abee9f7, + 0xed463ef9, 0xbb95e7fa, 0x36f3cf09, 0x761c6e08, 0xd067aff1, 0x078053f7, + 0x2f995e95, 0x837e73af, 0x6ff3e740, 0xb2a98f76, 0xeeb845ee, 0xaef6becc, + 0x50587ef6, 0x5f842e6f, 0xc6b1f990, 0x49afe1c8, 0x885f7466, 0xba25ec90, + 0x125dc780, 0xf83b0f94, 0x0de10b39, 0xe627c923, 0xf2937b05, 0xe44e6574, + 0x85058143, 0xcffaa3eb, 0x30fbe1af, 0xf842e7c2, 0x12c98efb, 0xc74cdbf9, + 0xca3b6dfd, 0xd223d01d, 0x4e10dac9, 0xf2b126b7, 0x67bc0731, 0x20f06aea, + 0x342e58cb, 0x2cdcb085, 0x3e7bbbc7, 0xaffc1134, 0x846cbe0b, 0x2a18a27f, + 0xe79af927, 0xee93341b, 0xcaf9e3af, 0x167f328d, 0xaefa06b1, 0xa26b3260, + 0x527598b2, 0xa1eb0779, 0xac5f83d2, 0xe03da364, 0x798cb2a6, 0x6aca9ca9, + 0x0d672ca9, 0x712b7e54, 0xc002625e, 0x51359d35, 0x39e402bd, 0x32890bdd, + 0xf74de319, 0xeecec89a, 0xac1cd37e, 0x0e6af800, 0x38bcb918, 0x577d2560, + 0x08466073, 0x1fddf9e3, 0x7bf85cd9, 0xa7b176a0, 0xbf48e29a, 0xf7f93ab6, + 0xbdd52e34, 0x2bb935dc, 0x78e3f77b, 0x7c7f421f, 0xbaad9e90, 0xafe27ba7, + 0x7a8f907f, 0xe1ade260, 0xe81cf27b, 0xcb6d5fcf, 0xcafe3f26, 0x9446dd40, + 0x5219d5d3, 0x7ab7e23d, 0x95ee8598, 0x05d3cee9, 0x415b2824, 0xe9fde3fe, + 0x05efe06f, 0xff26d940, 0xf901c05e, 0xde10f57e, 0xdab60eaf, 0x951e7f21, + 0x95377e1d, 0x5445fc47, 0xa87bf51e, 0x397f31df, 0x5efdc795, 0x9d1eaf2a, + 0x77c7df4f, 0x839e9fa7, 0xc87427bf, 0x19a4f951, 0xb28fe1f4, 0x44fc2e7c, + 0xfdf4eb08, 0x45aec0c8, 0xd508fdf8, 0xd7d67f41, 0xd19dd2f9, 0x555352ed, + 0x92ea1db8, 0x7008fdfc, 0x629e93d2, 0xea4527a8, 0x118dfdf8, 0xbc199ce3, + 0x57f3065e, 0xfb5220bf, 0x303f7811, 0xc72bd618, 0x2e094ca3, 0x03461f2e, + 0x74e18cbd, 0x7c65df83, 0xea99d5d8, 0x69762310, 0x4e5c13e5, 0xedc0be54, + 0xec67cace, 0x9eeef7f2, 0xef0d2132, 0x89cb511d, 0xf94c45f9, 0xbded13fd, + 0xea2c45a5, 0x83b9983e, 0xe60f2475, 0xd3f756ae, 0x4ce807ca, 0x95aad3bf, + 0x643a1f0b, 0x8d9733fb, 0x97faefc1, 0x1d93b1cf, 0xa76ec976, 0x763f7a73, + 0x0164a475, 0x44fbd5bc, 0x0ab413ca, 0xb5b07640, 0xeab8de7f, 0xced0136e, + 0xd7a7159d, 0xbeb1b8a6, 0xaefc49fa, 0x4ff352e2, 0x233aa4a7, 0xf4ec59f5, + 0xdda007c6, 0xddf56eb9, 0x2ffac0f7, 0xb8c0bd23, 0xfc0d5b97, 0x12939b1e, + 0xded32efd, 0x0b21af4c, 0x763f7bea, 0xa6ff3c33, 0x99bbf5e0, 0xbddbfbfc, + 0x2b41be99, 0xa7deab47, 0x1afd61df, 0x6bf133ef, 0x00dc2fbe, 0x8a7bed7e, + 0x7efbdb5c, 0xa77f0dee, 0x6dead976, 0xcea27243, 0x37d32c15, 0x658279d1, + 0x921e5fab, 0xa5cdf603, 0xe88d96e2, 0x7835ef77, 0xf942ef12, 0x71e06cd5, + 0xec904366, 0x89af4f80, 0x02466f34, 0x0609fbd7, 0x7c249f6e, 0x3d446a68, + 0x1382f603, 0x6bdcafbf, 0xa439f0e6, 0xc112572e, 0xc2c3ebc9, 0x86f1f1ef, + 0xf7b97025, 0xb25eb5e9, 0xd76e7ba7, 0x8082efd3, 0xc4faa07c, 0x6884523b, + 0x226f67bb, 0x8af3de7f, 0xcc52fd48, 0xf1e8c49e, 0x2f1debb5, 0xdcd7b7cf, + 0xc53f1aa3, 0xd653dfc0, 0xe36f9da3, 0x9de51324, 0x496e289e, 0xb2ebfcc3, + 0x207bfe12, 0x8abc3245, 0xa3f1357d, 0xe1a3dba9, 0xeeff289b, 0x26e4ceb0, + 0x557079fa, 0x7dfa38e2, 0xe297a742, 0xe71e73fb, 0x38f269f5, 0xe08e4520, + 0xdcb9e772, 0xf20cd153, 0x28657c39, 0x79e417b7, 0x8afd608f, 0xf510a7a1, + 0x24aab886, 0x33de0030, 0x9f495e3c, 0xd5d719f7, 0x6f34b005, 0xe1036468, + 0xcdcdc2f9, 0xa13df70c, 0x8a176cf9, 0xefe69499, 0xaf6d7c53, 0xd813a641, + 0xfe51998f, 0xa96736d7, 0xd7e60137, 0x391db939, 0x4245ac7d, 0x467a607b, + 0xf5f9d906, 0xcc1cc1a5, 0x308cf70f, 0x3a627c53, 0x9f80258c, 0xc5886c72, + 0xd412fe83, 0xcf58893d, 0xa7fd4c98, 0x86591d8f, 0xc658f87a, 0xb78c74f7, + 0x9e2bc7af, 0x5fc0658e, 0xc21fda0e, 0x8969cf57, 0x963eafbe, 0xf92a74b1, + 0xbd382315, 0x6c78cb1f, 0xd22bf62a, 0xc2cbee05, 0xf289a176, 0x70278fae, + 0x0c5d3f3d, 0x09efc71d, 0xcef819ef, 0x566ff471, 0xc77ec826, 0x622b9018, + 0x5c981fc4, 0x9f8edcd4, 0xde7b15cb, 0xeaea829e, 0xb73ff28e, 0x26f1e963, + 0x2f7aa196, 0x03ae3d9d, 0xccdf32cb, 0xe8731032, 0xf88e3caf, 0x70f55a9e, + 0x01ffd607, 0x88e3cafe, 0x55c992e7, 0x9f37fbf4, 0xa3e5dfdd, 0x7024e93c, + 0x7dc463d4, 0x4b09f622, 0x781af7e2, 0x485f5092, 0xdf7db86b, 0x7b244fb3, + 0x39751582, 0xea6e5c74, 0x33aafe90, 0x9e90d2bb, 0x38f207eb, 0x976715cb, + 0xfdf2ea83, 0xf322ff02, 0x57624541, 0xc561d21a, 0x9e0261be, 0xe1e2bd3b, + 0x56a04a76, 0x3061e7e4, 0xff2694cb, 0xd51678ee, 0x93fceec9, 0xfcf5ebc0, + 0xf3d676ee, 0x23ed237d, 0x2f10cf8c, 0xe30f0f3d, 0xeabe0170, 0xb92f5ef1, + 0xb983c33f, 0x52abf748, 0x87f21ee9, 0xfc24a72c, 0xe3302469, 0xae3e50d2, + 0xe276ca68, 0xef06cdf3, 0x15f71a4c, 0x96e389c1, 0x3c966cef, 0x2a4fd236, + 0x90f41e3b, 0x7ba7eed6, 0x3e32e687, 0xd126dcdf, 0x9aba0663, 0x03fcd2db, + 0xeecd2e81, 0x8ff7c832, 0x4d6bdea9, 0xfa9f74e0, 0x4fba66cb, 0x87ce1976, + 0xee81ab65, 0xab365d95, 0xf1443245, 0x3dd6b2cb, 0x577cafd4, 0xcbc5e533, + 0x2f64ecf3, 0xeb0d634f, 0xdf2d5f28, 0x53e3e457, 0xc9add3b0, 0x65003fcf, + 0xbe399fc5, 0x3efc53d8, 0x0f83f9b5, 0xbb2f91d9, 0xfc53960a, 0x942143e7, + 0xf8bd001a, 0x0ee76650, 0xc92e1ff4, 0x0fd68ef6, 0x0b1dfad1, 0xa2a7335c, + 0xdfd7d149, 0x38e8b660, 0xb03f168a, 0xdef11b1d, 0xa24d45a3, 0xd131ef13, + 0xfe0a23fa, 0x953f78b4, 0xc7db2290, 0x3f706320, 0x20eca69b, 0xfa71933f, + 0xd6017b20, 0x987dc971, 0xd39ab3ee, 0x6279efc4, 0x8a14a13d, 0xb3f06b03, + 0x8cda1f41, 0xd60549f7, 0x02fee819, 0x5c02fe1f, 0x8dfdac52, 0xec4a27ba, + 0xeb2d3f5b, 0x5bcf3ecb, 0x7a775fb9, 0x1b9f28bd, 0xdbcfb751, 0xb3247f97, + 0x26fbe31f, 0xeed27df0, 0xcfd002c7, 0xdf8217e4, 0xafa97287, 0xdfa5e85f, + 0xfed9b883, 0xdffff828, 0xc7a90a29, 0x00008000, 0x00088b1f, 0x00000000, + 0x7dedff00, 0xc554780b, 0x3d9cf0d9, 0xcd8dcd7b, 0x09c246fd, 0xb8094404, + 0x9fb1dc24, 0x4a34021b, 0x414045d0, 0x2dc8d812, 0x088d9242, 0x59b6b696, + 0x5a4062e4, 0x7da5aac1, 0x2c142ea8, 0x11a0d05a, 0x86ec5d43, 0xba8b4508, + 0x8ad45cb1, 0x14178026, 0xb16d0042, 0xfbdfad1f, 0xbb2733be, 0x6a2364e7, + 0xffefefd5, 0x27a3cbff, 0x9cccce73, 0x997ef799, 0x6318c399, 0xb17fc39f, + 0x50dff876, 0x261d8ac6, 0xd8c21b27, 0x4fab569c, 0x8a6c61c9, 0xef74676b, + 0xa79cc624, 0x18564c0d, 0xedfd2e6b, 0xd543262f, 0x8ad79b24, 0xcb7693f7, + 0xcd942f0e, 0x3b58eef1, 0xdaf4b7b4, 0xd5f6c468, 0x512c490f, 0x6724ac62, + 0x618b126f, 0x9b0e576c, 0x7783cae5, 0xd0daefe1, 0x950ed135, 0x6cdb1992, + 0xfb622577, 0x1b32dee7, 0x1ec60f58, 0x87f5e78c, 0xe3db99bd, 0xfd5098b6, + 0x687f5841, 0xd5b23ca8, 0x467f58c0, 0xe8c79c3f, 0xb318a30f, 0xebdfca86, + 0xaf94d048, 0xa9a198bd, 0x68fac85f, 0x0759179e, 0xb38f9e68, 0xdfca6817, + 0xa9ad1b4f, 0xa4529d7f, 0x3fe84f29, 0xa27f5341, 0xbca6b263, 0xeb8ac8d6, + 0x63675e61, 0x8f4b5e8c, 0xd8463cd0, 0xb787040d, 0x478702d3, 0x683b584b, + 0x8576c572, 0xa98d5957, 0x7dec35a3, 0x9c38da0f, 0x819c5d58, 0x4eec630d, + 0xffa899f5, 0x58df0143, 0x7be0d599, 0xdd46a303, 0xb5bc046f, 0x160d941f, + 0x42f32fc0, 0xcec614bb, 0x1a17768b, 0xbe207a0b, 0x7f7e01d8, 0xdfdf8d91, + 0xded1f025, 0xc335e0df, 0x816b5bb8, 0xde85fa26, 0x660c56e3, 0xdd7e1843, + 0x8259b28d, 0x730370f2, 0x17dd7be3, 0x1059cccd, 0x5163071a, 0xde76bdfc, + 0xe64e3abf, 0x8defe68c, 0xaedff7e7, 0xec62e245, 0x5d2b5a9d, 0x82cf0e7f, + 0xc0633e38, 0x691fa0cc, 0x34f8cc74, 0x06f6b7a0, 0xfa016ec9, 0x366c6cac, + 0xed17f8e3, 0x316549cc, 0x5ea7e15d, 0x31a6d78f, 0x5aabfa05, 0xd52ab2dc, + 0x1f6ef401, 0x682bf752, 0xe303555f, 0xb1a91200, 0x965bab0f, 0xbb62d8cb, + 0x6716f442, 0x7f43f981, 0xbff4feef, 0xf0073ccf, 0xd4b3fe3b, 0xfd07e47c, + 0xffb559f3, 0x17e8f4fc, 0x27f77f3c, 0x83f63f7f, 0xd3ff6a2f, 0x65fbdecf, + 0xc6eef3d8, 0x932ebb3f, 0x30746129, 0xace1cccc, 0xe90cb7af, 0x3b3ffa0a, + 0x358f1fea, 0xb2497f43, 0xe01d997b, 0x27cd7edc, 0xc51e0cd9, 0xcc34bf0e, + 0x37e2131d, 0x095ffb7d, 0xb1bc037e, 0xfb338018, 0x15b7cd81, 0x0ddf06e9, + 0x924b63e5, 0x5e906b7d, 0x669ac15d, 0x95b1f718, 0xe06b1c7d, 0x0ec7e53d, + 0x86f7338e, 0x2f3cb1f2, 0x24cbfbc3, 0x2cfb8307, 0x3a446acd, 0x5703899d, + 0x2b2ef868, 0xd31674e0, 0xf9d02dd2, 0x7c61adfb, 0xb6a96b33, 0x96d5ee5c, + 0x61fce387, 0xd899cf1e, 0xbc30fab4, 0xeffcc4fb, 0x047c2f89, 0xce3b8be5, + 0x5376e54e, 0xfac85dc7, 0xbfb4f58c, 0x81fa2d1f, 0x32008e39, 0xb7b2f1c5, + 0x9fcf34ac, 0xf89183e1, 0xf2266f3f, 0x4f82dbe3, 0xd6c4c4cf, 0x6707c049, + 0x6f070e14, 0xd2e1cc8d, 0xed056013, 0x6e2777ab, 0xdfc0b822, 0xb3ee5451, + 0xa4c7cb19, 0xde17b240, 0xfb07265b, 0x28cffbe2, 0x1d630fad, 0x4668e2ef, + 0x53b491ed, 0x10fa7c04, 0x30f3148c, 0xe7801f01, 0x69d946cc, 0xf1f0441b, + 0x29a3e0ea, 0xa8d0fe8f, 0x43af7f29, 0xa2f6be5b, 0xb4c85cb6, 0xdaac8bed, + 0x8e02cbf2, 0xfbdaece3, 0x96d34fdf, 0x1e3a55df, 0x1d8bf2e2, 0xf3c30dca, + 0x259521cc, 0xcfe00e2c, 0x179c66ec, 0xb864f78c, 0xc11e2b1c, 0x3adb78e1, + 0x21cbe7c9, 0x5f9e6afc, 0xecab1cc7, 0xdaf74879, 0x418bf0fb, 0xe82b9a7a, + 0xed3aee67, 0x19dfebf3, 0xbc019e35, 0xe325d84e, 0x207f78fb, 0x4e78881b, + 0x419f738c, 0xc744f03e, 0xc37d420d, 0x46b9ede4, 0xabd9ff78, 0xe3990e6c, + 0x3b21cb81, 0x3938ff1f, 0xe7c011c6, 0x058768fe, 0xd3da2d6e, 0x8fe51527, + 0x37cf5eda, 0x52dc800f, 0x9c7be1fa, 0x99af4867, 0x25d20559, 0x28fa021b, + 0xe4c2c81d, 0xf6878f8c, 0xceb71dcf, 0x3be04772, 0xef955ce0, 0x77c8259c, + 0x35f4e63f, 0x1ec8cda6, 0x352c71c7, 0x9c20b26d, 0x8fc427eb, 0xb999fa03, + 0x5b9df38c, 0x3064ac0a, 0x647b99bf, 0x25cce782, 0x44498f92, 0xf435e72f, + 0xbea0f022, 0x5e71f00f, 0x329a5fc7, 0xfdd12850, 0xecc62683, 0x678ebef0, + 0x1466df25, 0x648d53d9, 0xbb6d542f, 0x337047c2, 0xef1117b2, 0x2a8f816e, + 0xa81e2323, 0x0658fe04, 0x4bd4e7f5, 0x178fae34, 0xa8067c5b, 0x261db55f, + 0xae3fcf08, 0x2824f931, 0x3328dc7f, 0xbeb10fce, 0x7db550be, 0x7c2f2f3b, + 0xf82d96fc, 0xff3c5dbc, 0x2db8fb78, 0xa2b5bef8, 0x9062ef7f, 0x6ddf504b, + 0x3e6b5664, 0x0259b75c, 0x63b7a076, 0x4757f651, 0xe8ed3d21, 0x3e0cf0f3, + 0xc618c524, 0xab59c74f, 0x85d0e109, 0x9f03b69f, 0x2be575c5, 0xa0f1d237, + 0x50b9f4ae, 0x839039aa, 0x9267e372, 0x95d2ab63, 0xa974f54e, 0xc17cedd2, + 0xd9b3d01f, 0x1bca1035, 0x1d38f5f4, 0x1fd635ac, 0xb9e715b9, 0x3bfea642, + 0xb71009e7, 0xdc2d4902, 0x28c8f7d1, 0xdabe5e78, 0x32efe884, 0x33f3aecf, + 0x6ce6fcd1, 0x673274e7, 0xa453e4a9, 0xcfd5f3ae, 0x98bccbb3, 0xa63d956b, + 0xcebafceb, 0x218fd383, 0xf1104876, 0xa2d1be75, 0x9dd1fda0, 0xab5d3b7e, + 0xff411b64, 0x675adbb6, 0x238c0732, 0x2575bb7e, 0x907688c8, 0x179fa8c1, + 0xec5ddfac, 0x2d39be05, 0x4a6f7971, 0xf95874e6, 0x5926ea74, 0x6953f50a, + 0x4073f40e, 0x15e3bbbd, 0x81a56382, 0xc1fa09eb, 0x4e0f4e38, 0xc606bcd8, + 0x856de601, 0x32679fa6, 0xe361c937, 0x8604b4ab, 0x3b41fa69, 0x7c9fbc26, + 0x1c19cfde, 0x9fa85e4f, 0xf1da5daa, 0x9a839954, 0xfb0954f1, 0x0ce7ed48, + 0x9fea078e, 0xf784f1c1, 0x3c769cf3, 0x66a09655, 0x769d553c, 0x9f27e895, + 0xae55d3f7, 0x73f634f8, 0xb64e7d55, 0x2b4f0c31, 0xfb1631af, 0x0f4dd822, + 0xbff973c4, 0x7ecd9b70, 0x557eac32, 0xeca6bc7d, 0x9fb74c69, 0x859fa30c, + 0x3bc807f8, 0x032418b6, 0x314ad3c8, 0xfbb291c4, 0xa3d47881, 0x011faf49, + 0x5b559a0b, 0xa748cc3b, 0xfcfa5d8c, 0x865861f3, 0xcf1c653f, 0x38450394, + 0x1d93469f, 0xf00cfd59, 0x71e017bf, 0xf5f061c6, 0x7fddf986, 0x119b83e9, + 0x4dbb313e, 0x7940f709, 0xab45e3ad, 0xdb5fe302, 0xe5f62a68, 0x67dddea1, + 0x5f261d9d, 0xfdb93ad7, 0xeb019ccd, 0xfba181e4, 0x8f5f8331, 0x0cf17b43, + 0x5e2316b3, 0xd6031ad7, 0x587061c1, 0x3eaa2a0b, 0xc5765c02, 0x5fd744cb, + 0xb54b2e1b, 0x01e15170, 0xf085d9f0, 0x535b58f1, 0xffbb4ed0, 0x6871e39a, + 0x360d15a7, 0x9ca7a44a, 0x9721e912, 0xabaff39f, 0x0d7f2644, 0x08525626, + 0xf441bbf0, 0xfa0ad677, 0xdbf06ae9, 0xd885091c, 0xbc71c6ee, 0xd2f978dd, + 0x9e50c9a1, 0xca993dfc, 0x4d99eeaf, 0xe2600d72, 0x27bc0008, 0xbf258d4f, + 0x3863fa0e, 0x9fa8a9be, 0xe126d481, 0xa937682d, 0xe005f258, 0x308e377d, + 0xf3e70f1d, 0x796d4e49, 0x0cb6b172, 0x335f91fd, 0xafbda5d5, 0xe28759da, + 0x07de9363, 0xb1458c17, 0xfed1cf8c, 0x6632fa11, 0x1f6b5ef0, 0x11d9d718, + 0xebcd0766, 0xeca9dfd2, 0xb6c0c6bd, 0xa7337b62, 0xb28d9ffb, 0x84e796fa, + 0x443dfbd3, 0x030e4db7, 0x37fb6133, 0x9bd43e2c, 0xbb33db7f, 0x77a08b17, + 0xd198ed43, 0x35e34690, 0xdcfeb832, 0xfd8c51d4, 0x067bfcff, 0x8ffa0cb6, + 0xfb76651b, 0x27bfb422, 0x4231f85e, 0xef072dde, 0x2f2dfd0f, 0x256c728b, + 0x3f2148bb, 0x58b7f54d, 0xab2a1f5a, 0x340c967e, 0x34fa4419, 0x9e3d1076, + 0x81e9f7f7, 0xe68d8ce3, 0xa07f3c78, 0x2f6e1ed9, 0x047fa234, 0xd01fc676, + 0xa36b823f, 0xb5fd7fb0, 0x00bf2a76, 0x035e0e7e, 0x4ff90ab5, 0xd3fb6b7b, + 0x075ac5f5, 0x8ed7f75d, 0x5a81eba0, 0xb97bd527, 0x07ae98b6, 0x75745d6b, + 0xf9f025c7, 0xec5db918, 0x920afe79, 0xdbafe073, 0x88e28612, 0x3e20066b, + 0x793e3bcf, 0x0af0b7f2, 0xafd3a8cf, 0xacf5c116, 0x735771d4, 0x3ff9fc98, + 0x3f074fcd, 0x7fc71728, 0xef5d7f39, 0xb73d542f, 0x70179763, 0x87a9e0b4, + 0xfbcc18e2, 0x0a5d7194, 0xadcae1ca, 0x709ce32b, 0x0e3bb305, 0x9f29e1f5, + 0x3e891c5c, 0xfa54134a, 0x2848c670, 0xabe718e7, 0xefb89e8f, 0xbfabe406, + 0x51d9356d, 0x7ec0785f, 0xae7e80b1, 0xf89db86e, 0xbc6dca12, 0x1939ef7c, + 0xfe5a8dcb, 0x87bbf059, 0xa2589452, 0xb74e4cbb, 0xdba44c81, 0x8def2dea, + 0xb0f23a47, 0xfad3d20e, 0x8bfef876, 0xbd4f7a00, 0xbd7e8e5c, 0xffcab9fe, + 0x9eae411e, 0xc9cefb86, 0xab57f871, 0xafaef119, 0x0e34815f, 0x41313c7c, + 0x3670f1f0, 0x156ded1c, 0x4c97cc1e, 0xf73f2cfc, 0xa86d419b, 0x39fcb7bf, + 0xcaebca4e, 0x67ebe7af, 0xa507fa3f, 0x176cfe7b, 0x6bd7af74, 0x200c234a, + 0x7e7e8a15, 0xe20534ad, 0xb9fda346, 0xacf244c9, 0x1f6fc772, 0xd3da35fb, + 0x7d1c5a6f, 0xf69bb415, 0xe505191d, 0x494d3b85, 0x311a7c25, 0x2f084a52, + 0x696ff81e, 0x0b0f087e, 0x5667d99e, 0x77fbf206, 0xb1f08427, 0x99936770, + 0x8f0aec0d, 0x7326faa2, 0xbc044c6b, 0x478db7d4, 0xfb9f96be, 0x7ef119a7, + 0xa58905ea, 0xe78044e6, 0x6e717da6, 0xa3c22701, 0xde2753c0, 0x803df574, + 0x1553a417, 0x57e7fa4f, 0xc67a7027, 0xa23c94fe, 0x00ff27e7, 0xcb78a9f0, + 0x57f9c0e2, 0x1c67793c, 0x6303e3ce, 0xdfeba70d, 0xc2714cac, 0xde4c2b7b, + 0xf95d3b14, 0x96478afd, 0x6fcdbd10, 0xc8c29259, 0x1ba670ee, 0xd33cd046, + 0x37737e71, 0xcdf9a54e, 0xbba26e63, 0x2ec8df8a, 0x353e2bb4, 0x119de2b2, + 0xc175e2f8, 0x066c1f17, 0xfbf3046d, 0xef73c840, 0xcb8fb2eb, 0xca183bcd, + 0xdcaa25c9, 0xfca88b64, 0xe9e395a9, 0xe08304f1, 0x70f2e02b, 0x6f72dd7a, + 0x51f3f110, 0xfd153396, 0xbf030f47, 0x7d21f797, 0x2dcafd0e, 0x7e3952e3, + 0xed4cbdb8, 0xc2290ec0, 0x683f58fb, 0xac3b7f22, 0x273cfb1d, 0xe2c5fef4, + 0x28ee30fd, 0x07f3e409, 0xd36edc29, 0x095fefcf, 0xbf028e3c, 0xafa30b20, + 0xfce6fe30, 0xe73565be, 0x7ddf956f, 0xf9f18a93, 0xff388727, 0x7cccbb60, + 0x9520571a, 0x914d379e, 0x58581e48, 0x6f5f1220, 0xd6be0931, 0x04e9573e, + 0x38c46dc6, 0x60bd2746, 0x7f0409ff, 0x3de787b2, 0xe4c2ed08, 0x17df07a1, + 0x953fb5d7, 0xfe0be76f, 0x3ff9057f, 0x6cffc43a, 0xeefbe723, 0xf097adf5, + 0x3df26957, 0x57e46bf6, 0x82af4fe0, 0xe1726afc, 0xdede3fbc, 0xf456e47c, + 0x3e55eb1b, 0x3d4fcad5, 0xbd3c569f, 0xcf53e88f, 0xefd71fa7, 0xa7c8894b, + 0xb4a5f73b, 0xd3e245e6, 0xaa7e56ef, 0x2754fbf0, 0xd879553f, 0xf2f51c1d, + 0x250481f0, 0xdf843ca2, 0x2bac3621, 0xa774a9fd, 0xdf82dbd2, 0xb942f557, + 0x2a9749d3, 0xa5d275dd, 0xf9fa774a, 0x7fa7e16a, 0x158047fe, 0xb90df9e2, + 0xf7da1863, 0x45b8c153, 0x03054dbc, 0x6b1f34a3, 0x4d5f11a5, 0xfef3e311, + 0xb7184983, 0x79c21241, 0xf4bff54d, 0x0df7be19, 0xdfa2f313, 0x2dcf767b, + 0xab57da0a, 0x990ead92, 0xe68f84e4, 0x5eec8efd, 0xb00f7189, 0x8e51aaa3, + 0xdb47f74c, 0xddb96ed1, 0x32709eea, 0x7f448411, 0x8dcbe489, 0x07b2656b, + 0x2e3c79ad, 0xf2611ae1, 0x9efa5fa1, 0x2be345c1, 0xfd5e1829, 0xf73d1a23, + 0xb93dd1cf, 0x2157c606, 0x8c3f87c6, 0xc2ceddd7, 0x0f5faa7e, 0x46bbce5d, + 0xa1c5440a, 0xe3b12c3f, 0xddb87061, 0xefe32da7, 0xfd4252bf, 0x777eae5e, + 0x5f4df47c, 0x3aba05df, 0x1b787e0e, 0xba7c8d5e, 0xcb3cf4e1, 0xa9e8e1cf, + 0x031fc894, 0x615c9bbc, 0x44bad57e, 0xbddef72e, 0xcce280bb, 0xec0ff785, + 0x2e6de5c1, 0x423cd7c5, 0x2af79e7e, 0xa8af503d, 0x03f9eef6, 0xe8efe445, + 0xe822d3c7, 0xdec22ffc, 0x5a563b3d, 0x9ddf0327, 0x3f641d65, 0xd8dac779, + 0x6f7e08d6, 0x7ea7624d, 0xd430f260, 0x86afea4b, 0x4f13b0f8, 0x329e276b, + 0x7f0aea0e, 0xe5571dfc, 0xc3effca0, 0xe109f915, 0x1d6b62d9, 0xcf308aef, + 0x4adc047b, 0x46667ef6, 0x3f937639, 0xb8f084c7, 0xb1acac69, 0x28947f63, + 0x2b0144e4, 0xec9571c0, 0x246e2ebd, 0xec80e3e2, 0x3d5c01b0, 0xf76673fe, + 0x11c3cbc0, 0xf5fb47fb, 0x0f31c984, 0x67e278e1, 0x3e05e636, 0x45c44578, + 0xf51391e0, 0x44e5741a, 0x225f7dfd, 0x9bbc078f, 0x4eb82768, 0x2534292e, + 0x1af37bc3, 0x6f3183ec, 0xbfea2191, 0xf3d0a89b, 0xad4ed14c, 0xebc95197, + 0xd5ed99b5, 0x23dfe691, 0x6a5f53b9, 0xdefb35f0, 0x0fe8cd3b, 0xabe16fff, + 0xc0d8fef0, 0x8d5f8c18, 0x746e4895, 0xfc4663a5, 0x63fc1e70, 0xfbcf13f4, + 0x7cf2bc79, 0x02c38f09, 0x735db93c, 0x8d764493, 0xf87ae74a, 0xabe0273e, + 0x28a8ffbe, 0x9db913fb, 0x8557c2a4, 0x6abc7eab, 0xd757907d, 0x1bfbcb86, + 0x293f071b, 0x2fc23e61, 0x55d00dd9, 0x8cd5b1b5, 0x5c69e77c, 0x667f426f, + 0x65fbc2ba, 0x29a0d746, 0x6ef37461, 0xdbde91a2, 0x267a3f9c, 0xb585c7d2, + 0x77f38616, 0x871739ce, 0x8315f37a, 0xc8d1b5e3, 0xe4caaf7f, 0xc707778f, + 0xafdad6bf, 0xef0c6b1f, 0x39c68737, 0x84d0b2b9, 0x654669ea, 0x8c352993, + 0x4c4dde8e, 0xfdeae7a0, 0xf2854a8c, 0x1a3ef062, 0x16e7f787, 0xd5e49bca, + 0xc344c707, 0xf13519f3, 0xc02afe9c, 0x8e72a6f0, 0xbea68f26, 0x5347cf47, + 0xe535a24a, 0x3dad45d9, 0x96252e11, 0x044762c0, 0xa926f4fa, 0xf535f9f4, + 0x37e81382, 0x5ffedd02, 0xab1617a7, 0x9355a17a, 0xa92ebecf, 0x8d485e8b, + 0x2d1617a4, 0x0f115253, 0xd165be6a, 0x2252e34b, 0xb5c385e9, 0x1472df3c, + 0xcf5e19e4, 0x70bd014e, 0x985e9875, 0xd13a2362, 0xba482bb7, 0xf1505e8c, + 0x99cb1df4, 0x2217a8c3, 0x24f8f5f0, 0xd9b85ead, 0xe17a4e5f, 0x533229e6, + 0x497df3c2, 0x56eefec2, 0x4ca6142f, 0x11c9b2a7, 0x106e811d, 0x3a17189e, + 0xf8eef22a, 0x3f0fd41e, 0xbc13b24e, 0x3ba27af4, 0x39799e39, 0x04bffe39, + 0x2f8e555f, 0xbd912a9a, 0x18ee95d7, 0xe9a2efd1, 0x16ade512, 0x7c72e1ed, + 0xf1c81951, 0xae45d61c, 0x0eae50ba, 0xbcab9709, 0xeb9bb57d, 0xce634f01, + 0xf9e14b2f, 0x0e4cebad, 0x35bfd42b, 0x85876724, 0x271fd9cb, 0x2b672375, + 0xe0bd9cb8, 0x45f1e82f, 0x4263cb71, 0xcafc82be, 0x8ba04475, 0x9ad1a569, + 0x06270375, 0x19ef29ff, 0x64578fe4, 0x27bc878a, 0xc1c1fdf4, 0xf6821a7f, + 0x0f1c61ff, 0x49b7efe0, 0x9f80ef5c, 0xe058fd71, 0xdc39a2fb, 0x2edaae5e, + 0x1baafc13, 0x6f57bf38, 0x3d0e2893, 0x3333ff3e, 0xf0f6ede5, 0x971a86b8, + 0xf0bff156, 0x9955d695, 0xc4937cf8, 0xfc0acce3, 0xcd87cb0b, 0xbf242c73, + 0xad06fe64, 0xe96250ff, 0x4aed8fd8, 0x3639277e, 0xec8bfc91, 0x7e89556f, + 0x3ed36e16, 0x16ac72af, 0xe48057fe, 0xf6bd5576, 0x5fc15ef9, 0xde40e573, + 0x7bcf9833, 0xd244764d, 0x4ebd6a67, 0x9bfc5478, 0x780168f0, 0xf0eaf90c, + 0x44dfddb8, 0x0baf9379, 0x5ffcfd07, 0x3e46e554, 0xf6fc821b, 0x7249c19e, + 0xcf32fbc3, 0xdf59ce3b, 0xfe3c3537, 0x8ba0bafc, 0x55ee0c57, 0x9aaf58e9, + 0x6fe73fe7, 0xca1a8704, 0x306cf5a5, 0x37f36efa, 0xa76bf568, 0x48506f3e, + 0xecd6975f, 0x43cb6e94, 0x5abcf3b8, 0xf8fd6f85, 0xb65e780c, 0xd437f414, + 0x716f9d9f, 0xc5a8fc63, 0x517241d6, 0x05cfcfa5, 0xe053fcbf, 0xc74644e3, + 0x8d3bd258, 0x2ef89d92, 0x087ae360, 0x728362f0, 0x8fbfc8f3, 0x5bb07817, + 0xde392f88, 0xe427803c, 0x517ef1db, 0xddf6e7ae, 0xee39ff0c, 0x4c9bfbff, + 0x91a2aed8, 0xa0236baf, 0x8c3be986, 0x84a61447, 0x1b4f73e1, 0x92adefa7, + 0xe0f86e83, 0xe7c197df, 0xdaa8f065, 0x9f165f23, 0x4f3e5c2a, 0xc0827e12, + 0x582d8b6b, 0xfc798052, 0x3363923d, 0x53c7f656, 0xbae4e15c, 0xd8df843e, + 0x3d578e64, 0x80dfa3dd, 0xf2d4a6eb, 0xfa201c24, 0x7636c5f4, 0x6f6f7d42, + 0xcb855f6e, 0xa3be351d, 0xbe6abf5e, 0x1482c3cc, 0x66f352af, 0x83f76523, + 0x7257a889, 0xa44f5a25, 0x4660cfe6, 0x40dfd7c4, 0xbe9313ff, 0x66967fa0, + 0xecedebe7, 0xe13b7dea, 0x6e5136e9, 0xb4761ace, 0xa17be014, 0xbae0764e, + 0xca0c5bb4, 0x9e506b91, 0xe43131ac, 0x4d070b8f, 0xa3df2e4e, 0xbf949f49, + 0xfa84c272, 0x82731cb0, 0x09ffc798, 0xc4271bd7, 0x3d02de78, 0x2898c4ec, + 0x093a1fab, 0xd1c53fde, 0x9cf30e34, 0xacb48753, 0xe4ee38c4, 0x2391fb22, + 0x32d5cf88, 0xaf1e7c43, 0xeb3f222b, 0xe2243bce, 0x6f0037af, 0x94ea7ed8, + 0xe047239c, 0xc97565bd, 0x75295314, 0x0d3cdf26, 0x6507a5ca, 0x66f50287, + 0x831b18df, 0xfd09d7f1, 0x830ee665, 0xae0b194f, 0x6957f8c4, 0x71531dcd, + 0xe7a015dc, 0xe15d1f30, 0x8a97196f, 0xb5128de5, 0xe6dd78f7, 0xe09d2054, + 0x21e67386, 0x5079fef0, 0xd9eec10f, 0xb679ebc8, 0x754c0e48, 0x27aff3cd, + 0x8b6f3879, 0x598970c4, 0x2b58ec10, 0x8567d7ef, 0xa11b837e, 0x63e7943d, + 0x4b77ec7b, 0x90d3cdfc, 0xd49c618f, 0xfdb2c47e, 0x41e72f28, 0x82cc783b, + 0xfea0ee5b, 0xb128df6e, 0x62afe834, 0x47cfce44, 0x4d077f60, 0xb47e7c0e, + 0x671457e9, 0x4bef099f, 0xcb67fe87, 0x9d68e3ad, 0x3b258fd7, 0xb92abbad, + 0x5677f099, 0x9b4b19f0, 0x47baf64a, 0x6f3daa62, 0x3edb8f0c, 0xe89bdc96, + 0x65d2de78, 0xad5e70ab, 0x031ce4de, 0x5a39d5d1, 0xe0127897, 0xf43b06ed, + 0x83c79984, 0xcc27bd9b, 0xb37261ad, 0xf10fb939, 0x42c69ce5, 0x3aea2f92, + 0x6e32f70a, 0xb4adb467, 0x36987ad1, 0xef1b3d93, 0xd0b4af37, 0x5c1df6fd, + 0xb567b4bf, 0xdc7e83be, 0xcc4d1b07, 0xbe5c630b, 0x88c3cfb1, 0x9bb60fc7, + 0xdfe4de88, 0xcd8e4898, 0x5be3c1df, 0xbf791bcd, 0x72e36c1f, 0x5337e8ad, + 0x9ebca3c7, 0x42c9f20f, 0xafcad3f3, 0x1e02ca79, 0x89b75d47, 0x9557cbf4, + 0x53e45d53, 0x5f1455cf, 0x7aef4eec, 0x77aa8c58, 0x5ebe31f2, 0x7335955e, + 0x196fd203, 0x03068c4f, 0x087d3fbb, 0x2c6569f5, 0x46d53bc3, 0xa712c3fb, + 0x96c7ca07, 0x8a7e77fa, 0x6a515ff4, 0xde1e2073, 0xbf23f847, 0x78a44dac, + 0x395f3cea, 0xab3e79c1, 0xdfcf3821, 0x356fa5a0, 0x2ddd386e, 0x9eb86733, + 0xce6688aa, 0x7f477ab0, 0xef0a7402, 0xf928d599, 0xdb96126c, 0x42192ff6, + 0x6b8d3b65, 0x6bfbd0a9, 0x8f8e8963, 0x4adcf0fe, 0x7799d3a4, 0x6eed0c4b, + 0x42af75e6, 0x41bd57bd, 0xd6bd7052, 0xfb79bbfc, 0xc71ed0f9, 0x9c57f47d, + 0x15ae809e, 0x8deafba4, 0xfd53f7eb, 0xfd82922d, 0x4e54dd1f, 0x57854276, + 0x4b7cf466, 0xa001f91b, 0xd30f2897, 0x905395ec, 0x5857abee, 0x57d798ec, + 0xc7a547e9, 0x661f9136, 0xc9a0c756, 0xb2516ed0, 0xe50e9112, 0xdea75269, + 0x78f17a44, 0xedb57d39, 0x25903930, 0x7c8f4f2e, 0x6f4a825d, 0x90dbd232, + 0x6f35bd10, 0xfd23322c, 0xebe3e07d, 0x5e908a11, 0x571f1e91, 0x262c2ae3, + 0xe9523edc, 0x07e80ab1, 0xe8e5f4e5, 0xd3fa3bb1, 0x02f81dd3, 0xcee47eb4, + 0x771a3695, 0x37ddaad1, 0xc47ce52f, 0xab459c70, 0x8179487e, 0xff1e4679, + 0xeb88e156, 0xd24f30da, 0x2e0f1c65, 0x997fa733, 0xf1c6e8f1, 0x10d8e48b, + 0x96e803fd, 0x01bac59b, 0xe5039443, 0x5698c4d3, 0x31e304a3, 0x51187525, + 0xe14f0f3f, 0xc23979fa, 0x3325eb0a, 0x67281f5a, 0xacee081a, 0xa3d7c297, + 0x876476e6, 0xa67b63c7, 0xb06efea8, 0x189fde27, 0x5851e50d, 0xff404db6, + 0x5745a26e, 0x60a061ee, 0xbc516313, 0x5eca2a9c, 0x4c9d0328, 0x479f54cc, + 0xd12f72f3, 0xebcd1bde, 0xc79f500f, 0xead5f2f0, 0x7f5e18f3, 0x99e7a334, + 0x7013b129, 0x14cf573d, 0x237c66bb, 0xfd0d4951, 0x62d957fa, 0x6eb489a8, + 0x9a8a6fa7, 0xaf146787, 0xf4fff976, 0x5cb5e606, 0xf90098d6, 0xe9d34e07, + 0x867b30d6, 0x13ca7589, 0xa4b23d04, 0xae0bb238, 0x2f01bfc7, 0x26818c13, + 0x06b06f6c, 0xb0573f08, 0xfbf7f615, 0xf65222e3, 0xdd05e7e0, 0x56a86bfb, + 0x6ff30fde, 0x4b632725, 0xc524ae81, 0xe590f94e, 0x46db994b, 0xed4b94eb, + 0xcc49bf68, 0xaf9cf869, 0xfbe17657, 0xefa8f1d5, 0x802e32ef, 0x7c2131b4, + 0x1fa91b5c, 0x07675c75, 0xb798bc5b, 0xfd618ef4, 0x74e0c26b, 0xf08ae916, + 0xe22264b4, 0x098daced, 0xac728bbc, 0x8447fcfa, 0xeaf1b3d7, 0xd64e5173, + 0x95d74f3d, 0xa4febc4d, 0x78272b94, 0x64b3bde1, 0x6814a4e7, 0xd0c73163, + 0x28baeaba, 0xbee5debe, 0xed17b764, 0x5a73a023, 0x32cde497, 0x76317f93, + 0x5f0ce488, 0xd043315f, 0xb114b1f5, 0xaeb2d94e, 0x0ded05a6, 0x4196c3f0, + 0x0ba5cf7d, 0x4c4f8c66, 0x9199b7f4, 0x401baaee, 0xcb15e26e, 0x68dd5798, + 0xf75a4676, 0x56452a76, 0xf59a17e3, 0xfab2fbc0, 0xb9424cad, 0xafcb873c, + 0xc7e3bb45, 0x39517961, 0xbd6ff7b7, 0x0438e766, 0x69ab9941, 0xb1675e25, + 0x8a687dd6, 0x74517ea3, 0x4edc25fa, 0xd449ab2e, 0x03ad6794, 0x75c20e6c, + 0xfef5da99, 0xa7b9e44c, 0xe30fd0b3, 0xde04d38d, 0xa5ada7a7, 0xb774f7bc, + 0x44e73d76, 0x026332ff, 0x2246bb8e, 0xb8e6093d, 0xf066ed82, 0x6c35c219, + 0x7dc0385d, 0x67d0a35c, 0x97ce5c95, 0xb4a97f0a, 0xdd17af82, 0xc2666597, + 0x7f71f2df, 0x84d8fd6a, 0xa3f71421, 0x7f1efef5, 0xcfeb098b, 0x137e0258, + 0x4ec97bf7, 0xda0ea598, 0x86e60ceb, 0xe3c61b8d, 0xe755fa45, 0x3ee50d35, + 0xf5edc3ae, 0x10ed09be, 0x5d668f98, 0x6d0a8ce9, 0x5b46acb9, 0xf733afd6, + 0x3b3908a5, 0x7e400d80, 0x19229adb, 0xf944ff89, 0x5791d674, 0xefae0a03, + 0x194b6d74, 0x0747eb4a, 0x295ca1a1, 0xf9dca9bb, 0xe6a81cdc, 0xc78c07fb, + 0x25cf895b, 0x26e5dfe2, 0xe310bda7, 0x0fdc5529, 0x35cf819e, 0x7d7806eb, + 0xcb5dcb2a, 0xfee14d7f, 0x6b9b72da, 0xc12dc531, 0xc13cc54f, 0x98d3a358, + 0x307c4790, 0x7b3c922d, 0xabffd05b, 0x8c15b40c, 0x25121fab, 0xe4dfa5e0, + 0xcf8c3e1e, 0xb963fbf5, 0xfd53e317, 0x0aef000a, 0x779e05ca, 0xaef2209d, + 0xb33e8037, 0x5c9fb5c1, 0xc7f48d3f, 0x176e66d5, 0x2aac7c8b, 0x6b8f9c4f, + 0x7a13b1f3, 0xe50cf81e, 0xd61b0dce, 0xdb99ff92, 0x1ebf99c7, 0x8d9f77c6, + 0xddbeffbf, 0xcea98fdc, 0x35f24fdb, 0xf4f229d5, 0x36ce4269, 0xe7559c82, + 0x454df80f, 0x64fe87b9, 0x37bd1e49, 0x87bd73bd, 0x14a4e493, 0x1cf86318, + 0x78aa57e4, 0x0a599def, 0x41652bc1, 0xcef384bd, 0x6865de62, 0x6819ff37, + 0xd7abef0a, 0x533ebdaf, 0x56ebf491, 0x541d2067, 0xf58ab5a5, 0xdfcf5faa, + 0xe7fe82fc, 0xf7d41ca2, 0xebe7d30f, 0xec4ced04, 0xf144b847, 0xde2e3540, + 0xad917e9d, 0x30dc8d06, 0xf234a3d9, 0xad7f4265, 0xd0e899bc, 0x471b99ca, + 0x9f3cd1f4, 0x79a01ce4, 0x40b8b93e, 0x1aea9e53, 0xcb7fa9ad, 0xd94d22b4, + 0xa6bd7692, 0x49b94dbe, 0x7fee8e53, 0xac7ea6ab, 0x73cd36e3, 0x4ecf4bcb, + 0x662e0093, 0x0dd5b7ab, 0xde03a870, 0xd2109118, 0xace2031b, 0xaa287eb4, + 0x6c7e46c0, 0x004b60dd, 0x832ea4e9, 0xbcb0d3ef, 0x002d24b4, 0x6c7b58fd, + 0xf5c216b7, 0x0c6f92f7, 0x62ac73c6, 0x7755f61d, 0xf95e8d33, 0x2be70665, + 0xaa657af5, 0x5c1a687b, 0x9929b6f3, 0xf068048c, 0x358fc42a, 0x6bbb718a, + 0x7437df17, 0x91cfea35, 0x64967ea1, 0xc54a0e15, 0xaf3b7776, 0x91b3bf23, + 0xbd42fbd9, 0x91bf62cd, 0xda999777, 0x1ab635e5, 0xfdfc619c, 0x0f2e5487, + 0xb98d721e, 0x32f8898e, 0x0deac3ea, 0xf7e8cdc7, 0x689bfb57, 0xd720e1dd, + 0x16f7da71, 0x9af42fba, 0xd70a23b1, 0x1f553d3d, 0xc2e23d79, 0x6bcd3354, + 0x65e390bf, 0x7f61644b, 0x2aa4f8f3, 0x7676cb97, 0x1b8c6404, 0x93e36954, + 0xf20d397a, 0xded76359, 0x7140223a, 0x11d3900d, 0x0f5545fd, 0x3cd6dc80, + 0x3af6859f, 0x7943275f, 0x9ae39023, 0x4553d3e7, 0xcb006b3c, 0x6fc275c3, + 0xe7110cb8, 0x1e0cdbf7, 0x5dc37ebf, 0x087f7044, 0xc21216e3, 0x0e2f0f53, + 0x69c1cbc7, 0x15bf9a87, 0x7bd7d2f8, 0x6be3832a, 0x3a723747, 0xceedca90, + 0x1f3052cd, 0x15c7a885, 0x033af445, 0x2014a5d7, 0x0ab6fe1e, 0x67b2a8fd, + 0xf4fa8625, 0xd12f4daf, 0xae33263a, 0xa438c24f, 0x6954bf58, 0x7fa19652, + 0x40e0f400, 0x31baa6fb, 0xaaafe340, 0xfbc2682f, 0xce3c8d55, 0xf1e069e2, + 0x4ad66acb, 0x6ee6dd7e, 0x2a6f75c6, 0x5207efa7, 0xc7bf1a15, 0xbd44ef0d, + 0xf9f160de, 0x2b7fc424, 0x76ca57c5, 0x941d6c4b, 0x4eb6af37, 0x3d2f648b, + 0xe2fde02f, 0xf5c3336a, 0x1ed095e6, 0x6b3fb1e7, 0x3be319bf, 0xca253b65, + 0x5bea7867, 0xd6be62a6, 0xd0c4d8b3, 0x77c7508e, 0x7e482b26, 0x84739be4, + 0xc787391f, 0xcc5cde2d, 0xee790fed, 0x9d57147b, 0xc8fc255e, 0x0e281739, + 0xf08566f4, 0xb8f2e723, 0xd43bf4c7, 0x8e968ebc, 0xd3d53a55, 0xf56e9e9f, + 0xe955faf4, 0xa76a4773, 0xf508319d, 0x1c7be03a, 0x1fdef1fa, 0x4c27ca32, + 0x426cd4bb, 0x2af7bf3f, 0x281ee3bb, 0x2b7d940f, 0x9ace5e31, 0x95c1f3f9, + 0x5f2e249b, 0x3e715b94, 0x86667599, 0x020239fb, 0x53c4014f, 0x43a94e32, + 0x357e468a, 0x1ca37b06, 0x0175c1ca, 0xc1a7c700, 0xf949dfcf, 0x065f2e25, + 0x69b6973e, 0xd6bd184d, 0xcaa2b908, 0xe66601bd, 0x017189de, 0xc6067d63, + 0xf8987717, 0xd16c963e, 0x1d3edf5f, 0xb5c127e3, 0x65ffbc4d, 0x7fcb5571, + 0x94fe10c9, 0x75c11673, 0x5da3c8a2, 0x8a5034bf, 0x744ec8f3, 0x6f315307, + 0x12a47d99, 0xef5d5af5, 0x1fd0f397, 0xabc3d751, 0x91e6f471, 0x13bc6c1f, + 0x32bb6be6, 0xdb69f08a, 0xf48edeb3, 0x243beb6b, 0x57de5235, 0x2a2e7abd, + 0x53fc0dcc, 0x5d37b17d, 0xbda4f2d5, 0x6dfd68a7, 0x78dcffb5, 0x698b8fe2, + 0xf76d5f74, 0x81ee3127, 0xf32cff62, 0x065e9127, 0x911c6cb9, 0xc2a7aa1f, + 0x68e75d41, 0xf085bbeb, 0x3c1de775, 0x7ad8c1bf, 0x654667ea, 0xfd0e548b, + 0x9a7262dc, 0x47de0062, 0x709b4c7a, 0xd5d71732, 0xc1c1b8f3, 0xa5c52b5a, + 0x53b5ad5e, 0x469b5839, 0x156bd7e5, 0xec915eba, 0x34e104fa, 0xbe9ac5f5, + 0xace6b708, 0xa7985d87, 0x44d07b3c, 0xaecc60f0, 0xc17de7d9, 0xea3c532f, + 0x5f5f0342, 0xe67f8ea2, 0x4ee60cc5, 0x8a6371e4, 0x0bfd2c57, 0xc54739c9, + 0xf7e8f1b9, 0x5b6cae0c, 0xd2cf6585, 0xee9d694f, 0x282fa03b, 0xe3c8d1ef, + 0x2d8d55a7, 0xf4b9ceb4, 0xb3f50262, 0x1e31d0c3, 0x82fbccf9, 0xde3beb44, + 0x4e673c69, 0xd288fae5, 0x7c451b3a, 0x3c5a4879, 0x1fe3c1c1, 0xe5f8e06c, + 0x8245d579, 0xfaae9a1e, 0xc3e21c47, 0xf5a154ba, 0x6407d522, 0x19acb38a, + 0x8f6711d3, 0x6e317720, 0xde93eb8d, 0xf494eb12, 0xbd99a7cf, 0xc07d717d, + 0xfde44334, 0x50b48ecf, 0x75d71f7e, 0xc7f53297, 0x3f83d7f7, 0xca88eb43, + 0x8ca745fc, 0x6ef9ad78, 0x196acff2, 0xfdf0c1fd, 0x320fe806, 0x34bdfbcd, + 0xae564b7e, 0x85d6ef26, 0x98335bfe, 0xaeaa7802, 0x20173003, 0xd7455f9d, + 0x2af7ddf6, 0xa8d637c8, 0x2f51878e, 0xf2067eb0, 0x5abcaa27, 0xe84b273b, + 0xee0cacad, 0x89a7173f, 0x2fc2b2fd, 0x4267ff02, 0xe27ff71a, 0x5f8d32f6, + 0x7e4fbfa4, 0xc7ec5591, 0x7978001e, 0xafb8c23a, 0xc2e318cc, 0x1d6cd976, + 0xfa0337d1, 0xcfd2ba46, 0x1f1a4673, 0xd3cfca97, 0x28f39f91, 0xacfc4ece, + 0x464877ef, 0xcfb40ce1, 0x5fb37756, 0xefc12aeb, 0xc1181b55, 0x8121b3cb, + 0x6d8674e0, 0x7a018d70, 0xd8e3033c, 0xd678f40c, 0x878e8ae5, 0xaedd67f6, + 0x109884e8, 0x886f57ff, 0x73ab76a2, 0x872c4a6f, 0xf7a08d72, 0x2b22c6f6, + 0x06e679c2, 0xfbea77ce, 0x4f4c09de, 0x6a1a3e44, 0xde6330ea, 0x2dbfa7ae, + 0xa1bbed0e, 0x222727bb, 0x4e3775ff, 0x779f3a77, 0xb445d2d5, 0xb87f155e, + 0xd0a1627e, 0x3a7b9e63, 0xd57ca11e, 0xdbf44652, 0xd5afebb4, 0xfeedbfc8, + 0x9e6bca68, 0x7a4d13d9, 0x3cd3ecf0, 0xd4c679af, 0xaa60eb4a, 0xf476cb77, + 0x7c2f3d07, 0x9ff230fc, 0xa1459767, 0xdeffbd78, 0xb6aeb873, 0xad1d7fd2, + 0xfedca8c3, 0xd541f2dd, 0xfec8bbd2, 0xd71fcb51, 0x37285d5a, 0x2e5c8ddb, + 0x867c6c2c, 0x9785d9ec, 0xfcc20c2e, 0xff3d99ef, 0x98e50c3d, 0x86178fe7, + 0xe7ec3ed1, 0xe7c30c2f, 0x6ba2e79e, 0xef25d922, 0x8e38f066, 0x0e731faa, + 0x9ef13519, 0x73fe8209, 0xc62bac56, 0xb6864d73, 0xaf84714c, 0xd7da1b1b, + 0x8617fb40, 0x389b1e1e, 0x8addac37, 0x392fdf20, 0xf46c65a4, 0x747a309c, + 0xb8d49866, 0xd38ad7d1, 0xa11fb130, 0x34132e33, 0xd5843ed0, 0x6f3f2341, + 0xa1f242a0, 0x8a7600ff, 0x4bd91dbe, 0xe44f6f67, 0x5d1832e7, 0x1d220613, + 0xf697dedc, 0x75af3387, 0x3d986e5f, 0xa0683d34, 0xfcd3ddf5, 0xefd90096, + 0xefad2341, 0x99a4ed56, 0xcd883ee7, 0x5dc42291, 0x0e3ebffa, 0xfe3eb6e5, + 0x6ec6b3d2, 0x2fef0898, 0x08ecc15d, 0x063c7d3f, 0xfb9db17e, 0xf8d75992, + 0xd07c128c, 0x5c95ed8a, 0xa7c71d83, 0xb78899da, 0x3efc0886, 0xb3f39d2d, + 0x822b47ca, 0x8ac7c206, 0x2e6b18e0, 0xe789275c, 0x7136a00d, 0xff0ae8df, + 0x1f18ade4, 0x96e97158, 0x9ef081e8, 0x626e8715, 0xdbbf20f7, 0x62fb58c7, + 0xb7df4bbb, 0xd10bcd4e, 0x4a7dfe89, 0x2127d73a, 0x7eb2207b, 0xfbfc178b, + 0xd8b9e95d, 0x3d6cfff4, 0x52757e07, 0xabf250fa, 0x07b8f067, 0xfaf5abf7, + 0x6abb9541, 0x7e04e3bf, 0x53ddcabb, 0xff80bf64, 0x5c77724b, 0x7af542ba, + 0x922527fa, 0x4a687c5f, 0xb5d312a2, 0x87463eff, 0x6baf2121, 0xe69daaff, + 0x59f73af1, 0xf2717fd1, 0x8a6796fc, 0x90a493e4, 0x4971e75d, 0xa9649f7c, + 0xd4f587c9, 0xf0a70571, 0xa754e9b8, 0xaa86f289, 0x87daa7fd, 0x3c1dcf9d, + 0x8bdaa8af, 0x74185daa, 0x94ec38f1, 0x15f9fc21, 0x106beec9, 0xf588ef5e, + 0xf247432d, 0xf6b98cfb, 0xcb747fa1, 0x7e2312cd, 0x4aa2f617, 0x527b7a9f, + 0x1ddf6f5d, 0xba0a371e, 0x5b2bf954, 0x9eaa17c7, 0xba7a11aa, 0x2274f51a, + 0x34cfe9ea, 0x5fbeb776, 0xf4aed3d0, 0x08c76c64, 0x1b0e43be, 0xeefc915d, + 0x375fa213, 0x3dae0fe2, 0xe2162f83, 0x7058b378, 0xdd8bfa19, 0xb0974fe9, + 0x5e7bba63, 0x5f9fc693, 0x08d78f8e, 0x7c577ffc, 0x9c3feabc, 0xbeed3b8f, + 0xba23ce6e, 0x7ef0a332, 0xb928dba4, 0x7c885826, 0xc51367f7, 0x4af5f5c9, + 0xff063e85, 0xfbbf4355, 0xf406ccb2, 0xdc153c77, 0x578bafff, 0xe4bf235e, + 0xd5d69925, 0x0eff042c, 0x1705b3ed, 0x44ad74ed, 0x33ae183b, 0xfe50b5b6, + 0x76854660, 0x831875fc, 0xe477f6c5, 0x32fc7ad0, 0x44e29636, 0x3b78fe65, + 0x4baf23ee, 0x86f5a7ae, 0xb2b2adde, 0xedfebc35, 0x8f2b7d6a, 0xf74d2d9b, + 0x6b79e72d, 0xab2fbe8d, 0x5af3dbd1, 0xc45a3ffd, 0x03b3ba7d, 0x71b26f9e, + 0x26407279, 0x78c6aefe, 0x998cd5d1, 0x4bd5f5d5, 0xdaa39c79, 0x23f68cbf, + 0x1fe78957, 0x4714831a, 0x5417fca2, 0x9f5fe53d, 0x9cc87c82, 0xd54f7cda, + 0x2724c396, 0x849f79f5, 0x3c8f2e06, 0xf3c8b295, 0x7d68930c, 0xa7d8a363, + 0x223728aa, 0xcc5c61dc, 0x863ee0a7, 0xce3fe413, 0xf325fdd8, 0x17f84e3c, + 0x7fb3cf31, 0xf972a65f, 0x63754f3c, 0x84fd098b, 0xde7be5cb, 0xc38cef49, + 0x97b09c50, 0x7b5fc791, 0xc63b25f9, 0xf5897a97, 0x4757c37e, 0xc77ff5f1, + 0xdf2224e6, 0x9f6978ab, 0xfed9e1c4, 0xd88527e6, 0xa331d86e, 0x3e11d71d, + 0xbfe2e6ff, 0xad32f264, 0x6c7f18d3, 0x25fa3471, 0x4516c7ed, 0x879f3c23, + 0xb9e3e22b, 0xe3118c37, 0x78a1e589, 0x7bd205f2, 0xb2788b77, 0x6c5ef411, + 0x6fa32e28, 0xd72153f7, 0x8adf30ea, 0xe79bb974, 0xddd2ebfd, 0x57f953d7, + 0x13ff69bd, 0xbcc279c3, 0xc63a019e, 0x9800cfb8, 0x9f95e62c, 0x302b628c, + 0xec9753cf, 0xe6f8997e, 0xf9050657, 0x7e53da06, 0x2153bbc8, 0x55a1883d, + 0x020cc3cc, 0x7da563dd, 0x8f944979, 0x2fe04ab9, 0xf452fc1d, 0x5334610f, + 0x403c8f30, 0x450663e4, 0x7ff62331, 0xe6bdc99f, 0x34ffcc4a, 0x88cb1d19, + 0x93891de8, 0x85e6bb62, 0x77cf2724, 0x3521f9ab, 0x7e5dddef, 0x0cf7c248, + 0xf945f4e2, 0x3094e620, 0x81e6ae1f, 0x4a2ecdd8, 0x511f2d4e, 0x7967e743, + 0x9d37d8b2, 0x8b4a29ff, 0xa5719f90, 0x6bef6131, 0xfa6b81f3, 0xfa744d3f, + 0x6b80f355, 0x71e9bfd2, 0xd5efdc2b, 0xfc487b8d, 0xa3f214f9, 0x3a77f9fe, + 0xffb560b7, 0xb3bde902, 0x0e71161d, 0x938f2b45, 0x2f144dfb, 0x58fe0b38, + 0xdd3e9872, 0xddfbc69e, 0xfa222feb, 0x8d8e086f, 0xc487fac6, 0xa687d5fd, + 0xde7b464c, 0xfa3a341b, 0x7fb848d2, 0x0e3410d5, 0x1be4fb45, 0x7a694bc4, + 0xa359f984, 0xf3d23eb8, 0xbfe09c51, 0xe70e0cb8, 0x5fb937a2, 0xf3cc59e5, + 0x1d75761f, 0x73cf0d70, 0x914acfef, 0x6a77f8d4, 0x6ec8fca4, 0xecbd2ebe, + 0x2df68976, 0xc8fcd97f, 0x7fb6c68c, 0x8fa23f2b, 0x219ddf3b, 0x790322f2, + 0xdd23b9dc, 0xa84bf34e, 0xfb885c19, 0x7ef9d49e, 0x901f7083, 0x43e6edf9, + 0xedf9efaf, 0x352fdff6, 0x837cdd02, 0xcb7d97fd, 0x96fc2ffd, 0xf52fbffb, + 0xdb7f85db, 0xcbffdcb7, 0x8fff72df, 0xff07d244, 0xf5ebe6af, 0xfe7d78f9, + 0xb7979f5e, 0x8bd734bc, 0xd695eecf, 0x6ae00476, 0x4d35db8d, 0x8c687902, + 0xbd4562df, 0xe7923259, 0xb58f56af, 0xa14936fa, 0xaf0abe3c, 0x3fdc5991, + 0xf39de7b3, 0x6ce356e2, 0x226c7067, 0x3246bbc6, 0xdacf6ff2, 0x198b1e78, + 0xd798e9ed, 0x37e99a82, 0x67521d81, 0x7d079c8b, 0xf7f0a7af, 0x4b1bd1ba, + 0xc8af0ab2, 0xfed5a64c, 0x59f648ce, 0xdb2f88ad, 0x17c5191b, 0xbf495199, + 0xa4abde89, 0xe3d3fda3, 0x2e3f7e45, 0x689b9cc0, 0x4dce4a5c, 0x928f6e74, + 0x407be383, 0xae1367e4, 0xf18397ef, 0x03b004e4, 0x1eb78f31, 0xa7e479f3, + 0xfa9ea9da, 0xdc99ddbe, 0xc4c07a4f, 0xef305ce8, 0x11dd7c95, 0xbd9156b3, + 0x0ee1e6a6, 0xcb27029a, 0x8dc3ca25, 0x62bff1c1, 0xce6de408, 0x449c4411, + 0x3f296dfb, 0xdfc8eaf8, 0x7bd377f5, 0x86fecd14, 0x6187f466, 0x29ee771c, + 0xb19dfa20, 0x6fed2477, 0x091ae4f0, 0x46fc5dce, 0x43780711, 0x38d431c4, + 0x7a8f9a80, 0xde3fc45b, 0x3f4ab8c1, 0xa1584f3c, 0xc34caceb, 0x5a9e77bf, + 0x159cfe57, 0x203d3f49, 0xf78fb8f1, 0x29f71e15, 0x84fa3b30, 0xccac7faf, + 0x0f2c78e4, 0x1a83bcf0, 0xcc4279c7, 0x7287e0a7, 0x687602c0, 0x6681aac1, + 0xab05ebd4, 0x3af0a2b2, 0xa433e9c8, 0xcfa7bc00, 0xf15069d9, 0xee8e8917, + 0x89f114ca, 0x8f941d03, 0x9797467b, 0xd7c99ddf, 0x7165e41b, 0x64ceeefc, + 0xafb3be54, 0x8b9a3971, 0xcbb1ae3d, 0x6541f291, 0x38e2f7e0, 0xb8f8ebcb, + 0x05977855, 0x4f7c2294, 0x558ebedb, 0xc8afcd78, 0x79b8a229, 0xb455b9e5, + 0x85d2e9bf, 0x1c52d7fd, 0xffa0accc, 0x1b55b330, 0xc5909b4f, 0xa0cfe7e3, + 0xbb708dc1, 0x6ffe48ce, 0xa24675c1, 0x1b32849f, 0x2609a7f9, 0x7960c726, + 0xf283b712, 0xb08a938b, 0x93c4a6cc, 0x407f97fd, 0x179b9f89, 0x5c256f8a, + 0xe11938b7, 0xa8bcb974, 0x22bb271a, 0xa44bf9d9, 0x179aafdf, 0x88783aad, + 0xf3aa7bd6, 0xe6a2e152, 0x8bcbbb37, 0x3c12ebaa, 0xd6689fc5, 0x1d8c7851, + 0x58ae31e3, 0xaccda7b0, 0xcb4b37ee, 0x0b4de509, 0x7ca39f76, 0xf51f9aa9, + 0x3b239cd4, 0xb199da1a, 0x3fa0017d, 0x4364e41d, 0xee9bcf2d, 0x1a7bfb12, + 0xae78fe61, 0xfe601ff6, 0xfcc3f578, 0xb50bfef1, 0xa81ae9fd, 0x6f75d075, + 0x7aba08ed, 0xcf28e7fc, 0x36a642fa, 0x8f99d75f, 0x084d5d93, 0x1d7cb0af, + 0x3af9f595, 0x63c78a39, 0xee303f70, 0xb41cf21f, 0xf42efc92, 0x7f42f797, + 0xee2d6fe0, 0x6aee385e, 0xd18597cc, 0x61d3bb45, 0xdb6c73c3, 0xe61b0e5d, + 0x4e9a0ac9, 0x6a847ed1, 0x15ce9063, 0xa6073ce8, 0x775f1ce1, 0x21b42feb, + 0xd79b2f7c, 0x79fffc6a, 0xd7932fad, 0x32f905ba, 0xf23f2439, 0x26e7065d, + 0xda701ebc, 0x87c986e6, 0x179e2ed5, 0x9bdb9d59, 0x5741eff8, 0x6139f8ef, + 0xe628adfd, 0xeb848a71, 0xf7e16d72, 0x79e2c89f, 0xb98904ac, 0xe4b1c922, + 0xbcb8df9e, 0xef648e4e, 0xf402bfb7, 0xc3d03578, 0x5abdf9ee, 0x71b4ae89, + 0x73c5d5b6, 0xdbb9e17a, 0xac2c37de, 0x69c38f2f, 0x974c6ce2, 0xde2eeb4f, + 0x40d8a336, 0x7bc2e2e7, 0xeb5f51b3, 0xd8cc62e3, 0xb9f5cd91, 0xe4739c53, + 0x582364cd, 0x5bdabc97, 0x173877cc, 0x362f4fea, 0xf3509e90, 0x46c5f96b, + 0x99f40b56, 0xa3e4d4bf, 0xb1b15abc, 0xff0b9e8d, 0x3f3d8570, 0x3bc9e513, + 0x8c76cd07, 0x60e3e9a3, 0x752de28e, 0xa3bda1bd, 0x6d7da252, 0x373fd65d, + 0xf8c38d36, 0xaeb660d9, 0x1bd42c6e, 0xe3b06b9c, 0xe5cbe57a, 0x3d85f2e1, + 0x219f8fa3, 0xa1fda15d, 0x2f5fa38f, 0xb0bd7ef0, 0xbf43ee97, 0x8fd43932, + 0x2f4f4eda, 0xbe94f68f, 0xbf7f2e30, 0x71456fe8, 0xc45ceafe, 0xa1818967, + 0x3c5158de, 0xd61b9ac6, 0x234f595f, 0x7986af5f, 0xbcf0a4bd, 0xe9dfcf1e, + 0x3caa79f3, 0x8cfa682b, 0x083efff6, 0x95f51972, 0xffc78d27, 0x3c285e0b, + 0x34227280, 0x1f9fae4e, 0x37bf534c, 0x7c6788e0, 0xd14fb45e, 0xb8a247bb, + 0x27c97e5b, 0xcca1a37b, 0x7fb4f15c, 0x773073de, 0xef939e39, 0xc50e3129, + 0x971e3afd, 0xc22799d4, 0xd7e4d07c, 0xf5c7ae2a, 0x075305fc, 0xa67e20b7, + 0x9d689a96, 0xa6d7e4de, 0xaae539d1, 0xba982b9e, 0x7c289ee9, 0xf3a25fde, + 0x56bf261a, 0x4f9f063c, 0x88c01ed8, 0xb3889b38, 0x3c193907, 0x7c88d278, + 0xfbb24572, 0x0537c827, 0xa89e4493, 0xa9e3eb94, 0xc62649fe, 0x7e8d46ed, + 0x1bface6c, 0xf3d479c5, 0x7d711204, 0x2f485e42, 0x7d01ec15, 0x57d21b15, + 0x7a9eaeff, 0xe09da7b4, 0x2be83579, 0x24c24f1c, 0x62ef4f9e, 0x77fc08bf, + 0x93ba7fa7, 0xc467a8bb, 0x529983f9, 0xad7d575a, 0x38673c60, 0x9d12e5da, + 0xfd1dd683, 0xcfec26bd, 0xb6ec6ef8, 0x76fd04d7, 0xf1a9aebb, 0xfd13c9bb, + 0x787fe7b9, 0x57f8489e, 0xf548be6a, 0x7b09fac7, 0x215ebd57, 0x7b7fbbfc, + 0xd12a013f, 0x1209fb88, 0x9827ef22, 0xbda12f59, 0xd827eea4, 0x3b856667, + 0xab3d7093, 0x73e44fd8, 0xefb41d91, 0x7aad6fd7, 0x7bce893c, 0xa0cc6dc0, + 0x9f485af7, 0x43fd8157, 0x63ff92f6, 0xe7ad3f1e, 0x1aabb1eb, 0xd496fbb5, + 0x5f616ceb, 0x50f9858f, 0x77ac459e, 0x91ce2f1d, 0xef21c508, 0x21c78632, + 0x59304a3d, 0xe3eb475d, 0x5c4d1779, 0x6438bbb2, 0x75a0eb35, 0x9215d5b3, + 0xb7c3f503, 0x91ec971d, 0xddaf5da5, 0x83cb9327, 0x42496e69, 0x706ad5fb, + 0xf8bad255, 0x6c7ef817, 0x66fa7c3d, 0x413c7971, 0x331e31e4, 0x6c787a73, + 0x5bfb4494, 0xe21c1f70, 0xf817b1f9, 0xf2c7973e, 0x35173ef9, 0x5feea16f, + 0xb79432b9, 0xea6ffda0, 0x1f7517be, 0x780fba8b, 0x00a886d2, 0x99f707da, + 0x1db8d3ea, 0x3c3a25eb, 0xf3d193dc, 0x6f3f0b28, 0xf8ce3f5d, 0x28c3c2ac, + 0xf37f0f87, 0xac88d176, 0x25a67108, 0xaffc2fc2, 0x98fb2eac, 0x30bffb54, + 0xfec6a86b, 0xfedeb2a7, 0x16f2a6ff, 0x6f9f0141, 0x32abde70, 0xe6f8ddbf, + 0xfc72df67, 0x7b247cfa, 0x4b88b976, 0xd9e7e9e9, 0x68bf552c, 0xbac34bbf, + 0xfae43fec, 0x8e524ebb, 0x2f6bb9d2, 0x542573f1, 0xcb175a39, 0xe4215ffb, + 0x547d7aa7, 0x914ceb5c, 0x884f5fe3, 0xe764b3e7, 0x0193a472, 0xc8f1b4db, + 0x78daf581, 0x098dd5e4, 0x40e0f29a, 0xc17ea686, 0xe79ade81, 0x69578343, + 0x237f0f9e, 0xd91e535f, 0x7f534a3a, 0xb46387f4, 0x68755ae7, 0x5ed791e3, + 0x2fb749bc, 0x2bf047d2, 0x6f0dca04, 0xad9d6457, 0xa15997a9, 0x8d56579d, + 0x96bd5e76, 0x2fcee826, 0x78e6fde1, 0x53ebf3b5, 0x025f9da7, 0xbef2d3e6, + 0xd4cd3e7e, 0xecf7a153, 0x61b1f7f5, 0x738a07bb, 0xa99f686d, 0xc1db99fb, + 0x6411786e, 0xffb69fdf, 0x9cd7d696, 0x06eda279, 0x79e6cf3a, 0x0379e199, + 0x5963dbed, 0xa3e3de80, 0x34162873, 0x661ef4c8, 0x1c9b0c0c, 0x9d1afe76, + 0xe9f28f4c, 0x911258a9, 0xf8b69e0b, 0x82fda04a, 0xe106275d, 0x7bf692fe, + 0xfbcb3e78, 0x31f14484, 0x841d6de6, 0x60584bdf, 0xa89dfc8c, 0xbcb8b2d7, + 0x9a3bbd3b, 0xdb49ebd6, 0xbf52669a, 0x3098b7f5, 0xdbd6a69f, 0xa849fc2f, + 0x3d3df7c7, 0x5e77d12e, 0x71e17c70, 0x27bbf54d, 0xfae71fa7, 0x89a3416f, + 0xb059efce, 0x9e3b676d, 0x0de0bd57, 0xe65b9d0b, 0xf48e76d9, 0x3b53d16a, + 0x469ece08, 0xd5a8bd99, 0x8273da57, 0x5db8f1b7, 0xe9154375, 0xff932841, + 0xf91f5d55, 0x9dcbecbc, 0xa9f0bb67, 0x00bcbb3d, 0xfccf85c2, 0x1ee30e2e, + 0xc6b7051f, 0xedbedf91, 0xeee9cf8b, 0xfd702e72, 0x173c2fea, 0x03fc23f8, + 0x2cc5cbe4, 0xdbcab9dd, 0xa9f7c512, 0xf7c2c302, 0xe8e087f9, 0xf1de78e5, + 0x6e7823e9, 0x3fa7e9fd, 0x5bc7047e, 0x8f0baff9, 0xadf498fc, 0xc3728ecd, + 0x3a61c4f3, 0x976d5bf7, 0x40e5cd90, 0xa3bfe3fb, 0xdfdbd2f3, 0xb7b038b4, + 0x641f3df6, 0xefb77d23, 0xe3052cfc, 0x8cf78b5c, 0xe2f078a3, 0xf0be8b67, + 0xb7486b7b, 0xe3e17ebe, 0x3e7375f2, 0xcd5f16b1, 0x38d9cd0d, 0x6f8033ce, + 0x9e75f38c, 0xc55f5cf3, 0xc456cdcf, 0x23dbcef9, 0xe5df8b9f, 0xc986e73c, + 0xed0f7e37, 0x2e7e069e, 0x75cf65cc, 0xbc78043e, 0x6fe04bfa, 0xbe716afb, + 0x9dfc6449, 0x4f003fc1, 0xb9ed6c8e, 0xcc369fce, 0xf8d7f47d, 0xdbb121ac, + 0x5f039d73, 0xb9ea6e02, 0x72ccfffb, 0x3e46ce8e, 0x74f7fa7c, 0xade2368e, + 0x3a73c144, 0x7f46cd3e, 0x075343ee, 0xb1d72b9d, 0xefc762c7, 0x73d82d37, + 0xfda7f894, 0x64b71e59, 0x76fbfce2, 0xe7e3f9d6, 0x8a988b95, 0x3f2c4b67, + 0x1fc05a0f, 0xe2568bcf, 0x1738bee8, 0x7ab1d39a, 0xe777745e, 0xeeca2f44, + 0xf89cf5cd, 0x96d5401e, 0x9fb99abf, 0x3497c21a, 0x7fe9f682, 0x2adbf9e1, + 0xbfc2ec1c, 0x96dbc4eb, 0x7771e7c8, 0xf02f8f9e, 0x73c3f885, 0x35cf3a3c, + 0x5435f287, 0x08b28e96, 0x137da0f2, 0xbdbd2f3f, 0xeea9fd1b, 0xd6caaa0f, + 0x6798a9f1, 0xf2a1fc77, 0xffc6e5e9, 0x3333e155, 0x8bd0d15b, 0x97d3a70a, + 0x75f1cb22, 0xb6bfef82, 0x62ece3fd, 0xf48fdcff, 0x66d0d558, 0x44d9fbe6, + 0xf7cc547e, 0xf4dfd834, 0x6427a4fd, 0xd557e3b2, 0xd71c9337, 0x6eea8bcb, + 0xb39b6df2, 0x7153bac5, 0xa7e9c14e, 0xefb87d63, 0xdddef4ea, 0xf6effd7c, + 0xfa17b336, 0x19edbfdb, 0x721b8f33, 0xe13d41fe, 0xe9ff1b0b, 0x91069b27, + 0xdd66eedc, 0x8f78bd77, 0x3df91fc7, 0x34e7ed9e, 0xade859ef, 0x72efff27, + 0xe8c8fbef, 0xfbfb05bc, 0x3bf7c828, 0x4ffb847e, 0x17ffbc23, 0x176126d9, + 0x22eb13ae, 0x3f03de41, 0x9ee02bbf, 0x3cf5cbd6, 0x9d1999c2, 0xe3be1083, + 0x2725917e, 0xaf979f01, 0x7fa8ec95, 0x4c18af67, 0x9ccf9274, 0x89652744, + 0xfa937bfc, 0xe6cf1cf7, 0x1ab6fc7a, 0xc3fa4313, 0x280cded3, 0xb624eb7f, + 0x3197fb86, 0xe7425313, 0x6ead56d1, 0x0abc2389, 0xef3d533f, 0x3e66a2b6, + 0x39fd07c9, 0xdeac9538, 0x2d6fe78c, 0x2dcfcb58, 0xa38b9fd4, 0xcf5dab97, + 0x85fb5a89, 0x956df672, 0x81cc1cef, 0x07e7377c, 0xd7e456b1, 0x4a68f0ae, + 0xb3ca05be, 0x07a4c80f, 0x2eb0b854, 0xebcbfddf, 0x7f3cf881, 0x973f2fa0, + 0xb152515c, 0x3c1e9cde, 0xdd19282e, 0x597ef1c3, 0x19b87ba2, 0xb19beae5, + 0xb596c7b8, 0x7c50345d, 0x36595980, 0x59d9938e, 0x537db876, 0x60a7b26e, + 0x16cbc4de, 0x58fc51a5, 0xeb0addff, 0x1eff20da, 0x157bf683, 0x5f9c8965, + 0xeff3763a, 0x1e46b1ef, 0xeb32b6bf, 0x9c778c32, 0xe0a5d652, 0x95ae5411, + 0xc53dfe26, 0x4714f1ed, 0x91456db8, 0xba5fcf19, 0xf69e21ad, 0x93af30b5, + 0xe2a8cfbe, 0xc1456db1, 0xf7e834fe, 0x871cfab6, 0x269fc5ac, 0xaea0bc1e, + 0xc9dbc54d, 0x64ede0cb, 0xbe01bc24, 0x7a13f734, 0xeec5f169, 0xe94cf6e6, + 0x62fafb1d, 0x0d7ceefe, 0x77631eff, 0x340e92f2, 0x35c5094a, 0xe33a338b, + 0xef4829b5, 0x250ed617, 0x55f1e9bc, 0xc3d9affc, 0x7b337f71, 0x05ce962b, + 0x66c3eb2e, 0x6ff184dd, 0xd953f389, 0xa316262f, 0x8bd01ade, 0xb56bfdf3, + 0x82d9fe3c, 0x787ecff1, 0xca9dba6e, 0xf3fc4587, 0xe13fc628, 0x3fc626fa, + 0x7c527ae1, 0x33e5433f, 0xd7a20020, 0x7f38bdc1, 0x8925ee0d, 0x34e2ddf8, + 0xff8a4bb4, 0x73f38b25, 0x61637d7e, 0xce878d0c, 0xa3fef9cb, 0x7bd1bebf, + 0x3a37630d, 0x69b4f1b5, 0xb4f1b453, 0x663915f2, 0x736fd7f4, 0xa3d4d68d, + 0x0f5abc88, 0x925e98ba, 0x337e79a8, 0xbfcc34be, 0xf0a5ee2f, 0x1f7147f8, + 0x4b5bbd4d, 0x2a5bdfb5, 0xb3c668bf, 0x62dbd985, 0x26b3309f, 0x87bfc219, + 0xf1ca4402, 0x3e6de762, 0x416e3a31, 0x60e4fc7a, 0x5e7284b2, 0xaf150f8f, + 0x080037b3, 0x1b39dfa0, 0xbd97940c, 0x55e3b66b, 0xaeeccf3c, 0x7bf7f8a7, + 0x467bae4e, 0x39805df3, 0xbf84994f, 0xa1fb2763, 0xf232c568, 0x607dca3b, + 0xcb88022f, 0xa23ef45f, 0x467e3196, 0x0f91594b, 0x80bec90e, 0xe2727844, + 0x4fbd83f7, 0x7e47eff0, 0x0ed86208, 0x2b7677fa, 0x1287c71f, 0x53e5815b, + 0xfdfbb7b6, 0x6675e600, 0x0679bae2, 0x307c8dc4, 0xd3e2e499, 0x2cfa4332, + 0xe744c3bd, 0x587ede39, 0x31f4efa6, 0xc5533f29, 0xd9cbe62b, 0x1dfe1613, + 0x04a00e9b, 0x71f8b7a8, 0x8f9f7d0b, 0xcfcb0328, 0x11adf40e, 0xf2f48874, + 0xc6733c61, 0xfe7960d3, 0x6496a3e0, 0x82119f5a, 0xce106f9b, 0xfae09bd7, + 0xa3a02f51, 0x06f9e68f, 0x3bbafc91, 0x0f47f899, 0x2e6693df, 0xef48bc9f, + 0xea2e4852, 0x26d996ed, 0xc7df7d07, 0xa3a486cb, 0x96b93a5c, 0xf40f477f, + 0x3f5f1c4a, 0xabd134f3, 0x46939efa, 0xef8e3c65, 0xe90e5d64, 0x0ad6dbaf, + 0x06f4137f, 0xfae3efaf, 0x46ecbd6a, 0x275bc3bb, 0xaf9db9b9, 0x4db78fa5, + 0x688b9ede, 0xd68db1fd, 0x6809dcaf, 0x9dca3cc5, 0x2ec9533b, 0x5bec2998, + 0x2ddbc696, 0x3b3a73b6, 0x0f4fa07f, 0xea7ad7dc, 0xea01e010, 0x75f3a7b4, + 0xacc6a705, 0x3747861b, 0x1dec369d, 0xffb803f6, 0xfbef44f1, 0xc8dbc046, + 0x5ee6f76c, 0xac329f18, 0x4473c6cd, 0xfc4fface, 0xf50fbf1c, 0x83930ed1, + 0x97e974d8, 0x0c4ed3b3, 0xeb835d8d, 0xf2eb67c2, 0x3f042704, 0x5bf8293c, + 0x8b6fcfd5, 0xa7036cf2, 0x2482f63f, 0x34c46bbe, 0x9e217872, 0xe4872a43, + 0x2b872aa5, 0xc7fadd85, 0x3e6edc5e, 0x60a5d6c5, 0x4fa005bd, 0x3b3cfef1, + 0xb72a4bb7, 0x7ee7eff1, 0x4c9c7c84, 0xf5c31a7d, 0xe4167cf2, 0xea014e7a, + 0x77dd0949, 0xc0388b45, 0x409fbe3a, 0xb9e7f72f, 0xe06ffb7d, 0xa3003bfd, + 0x7cffe45d, 0x8f1b1ae6, 0x3c6deb71, 0xff97ac9e, 0xb9b7e84c, 0x3d7a7de2, + 0xbbe85730, 0x377d3ab9, 0xce8e71cf, 0x0edca91d, 0xb2b945ef, 0xc2efab4e, + 0x9a44a9e6, 0x872f3ce7, 0x873f3cf7, 0x769d7bcb, 0x08fda30d, 0x3d59dc2a, + 0x77b4d3fc, 0x791c61c5, 0xc33283fe, 0x78aa1cef, 0x823e66a8, 0xb02cc7f7, + 0x8f18ed0a, 0x062e31bc, 0xa1f0ba70, 0x2dc7ecbf, 0xa06b944a, 0x7efef3f3, + 0x9427b3bf, 0xa4b2f37b, 0x6f7efdfc, 0xd570aecf, 0x829bf1c3, 0x6ef9131b, + 0x9863076a, 0x377f85bb, 0xc91eac3a, 0x0901fffb, 0x00d0a8f5, 0x0000d0a8, + 0x00088b1f, 0x00000000, 0x3bedff00, 0xe5557469, 0x73dcfbb5, 0xe1dc8487, + 0xc2040464, 0xc06e49b9, 0x612f4865, 0x1213d41e, 0xde0d4b22, 0x00c10580, + 0x86120137, 0x7c07504c, 0x0040e3e2, 0xaa1a4583, 0xf50af8a5, 0x22d28342, + 0xb04a0834, 0xc141170c, 0xd6de8ba7, 0xa44f7d6a, 0x40932861, 0xd2bb6a52, + 0xf7b79457, 0x3b939df7, 0xed83a404, 0x58b593af, 0x9ef37efb, 0x77f7bdbf, + 0x52015000, 0xaaa8e601, 0xd08eceb5, 0x092bd00c, 0x72c06e60, 0xd80e35b6, + 0x37fc0ddf, 0xbb746b7f, 0x01e5e696, 0xf7473754, 0xa41c5fe3, 0xbfe6cc01, + 0xff5616a1, 0xd845cc41, 0x766f3d12, 0xe890eadc, 0x556679a4, 0x086e17eb, + 0xa1e6ca0c, 0x840cfada, 0x9f12a24d, 0x6e0f351b, 0xca7a01b8, 0x7773948e, + 0xde0bc361, 0xc5c2221b, 0x002300c9, 0x5c78174a, 0x439c1cfe, 0x2186f77f, + 0xb09e7468, 0x39cd23c0, 0x098a6584, 0x68c79cf0, 0xb1c6994f, 0x477f788d, + 0x617c67e2, 0xc1864ef6, 0x15483f08, 0x3a6f3c54, 0xeba236e1, 0x71eb15be, + 0xdf8841e7, 0x11f8137a, 0xcbbf5b9e, 0xfe3e47e9, 0x695dc5fe, 0x88772b04, + 0x66084410, 0xdcf015bf, 0x2f65f582, 0x56fb833f, 0xdaf78d6c, 0x88e2bbb0, + 0x3c7008bf, 0x252b7c0f, 0xe3d7971c, 0xe070c341, 0x71dd8445, 0x8428f23d, + 0xdfd982fd, 0x513de68f, 0xd927efe1, 0xd187faa3, 0xf4cc4fbe, 0xee3f7cff, + 0x04b6c4fb, 0x9248caaf, 0x44e1a682, 0x84041489, 0x7b7f0bd5, 0x04fc8cd2, + 0x9e8f83f1, 0xf2b8014a, 0xb6c408ba, 0x817f24ec, 0xcfdc4a9c, 0x703d05eb, + 0x5d29b89e, 0x22f6c4ca, 0xeff9ecec, 0x8d4ce7e7, 0x4fc4e59f, 0xd599e914, + 0xf3a50e1f, 0xbe70374f, 0x4d99face, 0xf397a7e3, 0xe7e73573, 0x339f8d4c, + 0x7e35788f, 0x4f892bca, 0x9f8d6af2, 0xeace1c0d, 0x3a7537c2, 0x4fc4f5e1, + 0xa7155e6c, 0xa60f885c, 0x173f909a, 0x4f508a76, 0x12a80b6d, 0x4485c3da, + 0xdf511250, 0x3f8d04ff, 0x7e610a0e, 0xe50ecdce, 0xd29e9106, 0xc49d47b5, + 0x453bb9d7, 0x3f2c704e, 0x73eee941, 0xc81f9e44, 0x24d53c25, 0x087942df, + 0x408aa5c0, 0xb7fbe12e, 0x825a7df2, 0x79e3e522, 0xde2dfbed, 0x36efc8cd, + 0x85c01587, 0x8384f676, 0x227265c1, 0x3a81679b, 0x505f3c00, 0xf8845814, + 0xdd3e50db, 0xb2159e90, 0x5905c6cc, 0x87ec5282, 0x7e13200d, 0x24288282, + 0x1d2fed75, 0x3e462283, 0x814c3bb5, 0x67ff48cd, 0x3c80d0d6, 0xffaf187b, + 0xe913b192, 0x03c835f8, 0xd252bce8, 0xccafc235, 0xfc8cd815, 0x6c4c0879, + 0x0cc087df, 0x982708a5, 0xd8713541, 0xba224f60, 0x3fa85990, 0xf1bf35e3, + 0x7410e1ed, 0xef82af21, 0x3fae7081, 0x73a55d30, 0xc14d0726, 0x1e0fe87e, + 0x090f0732, 0xb2714d08, 0x7c73c245, 0x913c84e3, 0x660cb0e4, 0xf15decf8, + 0x21f846db, 0x1326a5bd, 0x8129ebc7, 0x0a28f1d1, 0xdd32f89d, 0x8444470c, + 0x4439e28f, 0x5904b4f7, 0x0816f365, 0xa30ccdde, 0x54df8614, 0x2881bf0d, + 0x4bc87387, 0x0df76ddc, 0x3547d3d4, 0x069f707c, 0xf1cf5b27, 0x1edf9588, + 0xad004f8d, 0xcd6be256, 0x227fef63, 0x71359d20, 0x49f920f6, 0x6e5cb168, + 0x39f9afed, 0x48afe1e4, 0xc05f384e, 0xf4f90083, 0x04db06a8, 0xb87b3bb4, + 0x1e0d21ff, 0xa5ace8d7, 0xde0bca36, 0xdc5b0212, 0x03e73fb7, 0xd3ad8939, + 0x3b0347f7, 0x1026e34d, 0xed6bfc80, 0xb2562dfe, 0xbf5a79bf, 0xb22187ee, + 0x5dacde2d, 0x169f912a, 0x41ba6fc0, 0x8b3edad0, 0x13dc2958, 0x7afb25ef, + 0xa1ecdad4, 0x5e76277b, 0x5874df2c, 0xef53805c, 0x3e75f9a0, 0x03c03465, + 0x0bdbd3df, 0xcbda0a7c, 0xe39de1a4, 0x8e164a8d, 0x8e7f177f, 0x7828e864, + 0x452fc133, 0xd7253ede, 0xfce39685, 0x8a728f0a, 0xdcd39ffc, 0xa0fecc0a, + 0x58bbf191, 0x28061324, 0x28a37d1c, 0xb858f911, 0x6c9e605b, 0xe636e8ea, + 0x50f13a77, 0xd478619f, 0x76f413ec, 0x71bbc148, 0x36ceeeea, 0xb070a3c3, + 0xf27c6a2b, 0x9f1a8868, 0x1be91d78, 0x6a71b5a9, 0xd194f488, 0x4a8d9ff1, + 0x235b6c6f, 0x42dae3e6, 0x4ba74f3a, 0x65ffef0e, 0x835f19e0, 0x9d75d199, + 0xcc5075f9, 0xba6101be, 0x91df665c, 0x5dff223f, 0xe2a48229, 0xfc5f1aba, + 0x6117f26a, 0x3d181a7a, 0x8f9d78a1, 0xf1a37cd1, 0x06bfa442, 0x8d55f1f4, + 0x67cdf20a, 0xd2af9cea, 0x3f3ab1fc, 0x337f7d70, 0x7d6c4973, 0x4686a6d2, + 0x9fa61ed5, 0xbe18b3b5, 0x7c21ee49, 0x295fd339, 0xc42f48ff, 0x4ef906b3, + 0x5ca74557, 0x5f8c75d5, 0x6d1131a1, 0xa62337c2, 0xff022ddd, 0x52fc11de, + 0x59f949d7, 0x7cd2f811, 0x8b4a67c4, 0x127fbd10, 0xb4ddcf1f, 0x1d1d51ae, + 0x90fc036e, 0x5e8227f1, 0x9d299fc6, 0x9be75ef2, 0x6ac7eb85, 0xfee019fc, + 0x45e88fa1, 0x7d3972fa, 0xd2fd2881, 0x65bcaef5, 0x14b48aed, 0x2004b38a, + 0x68f2c37a, 0xe7fc91f2, 0x9bff3a4b, 0x586f8442, 0xa13dbc1e, 0xa9bf3f59, + 0x64abf491, 0x6f2f4eb7, 0xf70bf587, 0xbff216fb, 0xea7c7a21, 0x53f5e8f2, + 0x667f73a0, 0xf53a5357, 0xfa43cf17, 0xbcfc69e6, 0x4853537f, 0xbf76fae5, + 0x67ac353b, 0xad12b365, 0xed85bf74, 0x6be31b71, 0x93b8de27, 0xbc0fe380, + 0x07c7cd1f, 0xb27b79ea, 0xc1af9b7b, 0x4d7ed91e, 0x7764e3e7, 0x7d72bd94, + 0xc4fd1df9, 0x4024f37b, 0x161fbd94, 0x4487dba3, 0x437baf9d, 0xa750e58f, + 0x1f5efe7e, 0xfc0fb7dd, 0x719f1a30, 0xc7bdbd36, 0x6fe91857, 0x5f1937d4, + 0xf9f4fc74, 0xd7a25f45, 0xddaaf3c3, 0x729afa6f, 0x320cdee8, 0xc49a56ff, + 0x71c75c21, 0xb56a47bc, 0xbf68a938, 0xbcd00be8, 0xc2cf416e, 0x873d309c, + 0xff99169e, 0x8085eb56, 0x196cfd07, 0x04ba56c8, 0xa5628267, 0xcb90f5fb, + 0x9c15e8b5, 0x7169f87f, 0x3df70051, 0xc59928b9, 0xadb81f9b, 0x5d87ff8c, + 0x6366d37d, 0x0cc250fb, 0x0ef38cab, 0xc1963b3d, 0x7fe93bb7, 0x337a47d7, + 0xc9a5ce2b, 0x97e65df9, 0xf6f0250e, 0xbedbf72a, 0xd5af28a5, 0xe7ed996e, + 0x5ad2924f, 0x39e13f50, 0x09916c0b, 0x098fef4f, 0x6de7b2bf, 0xfc239f03, + 0x4695de96, 0x41ff2ef2, 0x9c4f5149, 0xe2c2be57, 0xab5e7015, 0x7c274a49, + 0x658dcffd, 0xb96b30fa, 0x18fbd506, 0x4fd5f83c, 0xcf749dea, 0x1c58146e, + 0xcd17f773, 0xbb62e7ef, 0x4bd321b2, 0x30e81ea8, 0x9ce78481, 0x202fdf5e, + 0x899dcaa2, 0x3c777baf, 0xbf340f9f, 0x7c7cbaf2, 0x2f9a60fc, 0xfe70cb4a, + 0x7017ec39, 0x712adcfc, 0x397840b3, 0x2404dd1d, 0xc097dce9, 0x2b73f0ae, + 0xb865816c, 0x7fbb69cf, 0x673a7afa, 0xd29605bd, 0x93d7413a, 0x4e5f198f, + 0x3f5cba4b, 0xa1cfcc6e, 0x2dbd3679, 0xca9f2195, 0x157a9d4c, 0x2aefbc04, + 0xb5fb7912, 0xb6f91f4d, 0x2f73fae0, 0xaaf163f5, 0x276ca19c, 0xa19d3d7d, + 0x3ffb20ec, 0x462ed5f8, 0x3c4bfb5f, 0x51d03b6e, 0x111e569e, 0x315c5427, + 0x68387d33, 0x7c231f95, 0x23eb760f, 0x6a2f2ca8, 0xf8a12e4e, 0xe28cf511, + 0x45ebd46d, 0x1f126ebb, 0x2645ba36, 0x4ddf43af, 0xea472d1d, 0xf9867ab7, + 0xde64e289, 0x6d6eea3e, 0x9cafd154, 0x33822db5, 0xfaf5e159, 0xe8aef9fe, + 0x39983938, 0x81d128e1, 0xca30c679, 0xeb7cf453, 0x0733f533, 0xf533f1c9, + 0xe3630653, 0x43a74ad4, 0xde7fe725, 0x1c9330e1, 0x9c979a4e, 0x62b938a3, + 0xb9f985a3, 0x8ba98d8a, 0x414e29db, 0x5740f17d, 0x2c32927a, 0xda5b9e8c, + 0x2beedaa5, 0x07191dec, 0x5dad7fb4, 0xf36a6eb6, 0x6d6fd935, 0x5b129597, + 0x2d1b4503, 0xcaabb23e, 0xa0330e21, 0xf1b31cbf, 0xefa42d9d, 0xf3e20b95, + 0xe578886c, 0x53931b46, 0x4aa1c3ab, 0x3a77ee38, 0xaf0889cc, 0x6e8c4dba, + 0x60cc8657, 0xb8e60881, 0x5397063c, 0xf10d711e, 0xc5f6c649, 0xa3ac2f45, + 0x0412e4b4, 0x3d430d26, 0xfd70a6bd, 0x0c5bb6bc, 0x66047e50, 0xf98c5cc5, + 0x7ee01cd3, 0x5dbdfaa2, 0x39fc7cd6, 0x41f2aea7, 0xf9f965c8, 0xfcfc98e9, + 0x8e1e7474, 0xfe51a61b, 0x30aaffcd, 0xc43b24de, 0x5e6a3d7c, 0xd51e7e44, + 0xf2d0c96f, 0xa3c83ceb, 0x9d5aee38, 0xdd829b25, 0x13da3b4a, 0x41b059d2, + 0x2e56f860, 0xc4360312, 0xe79920b7, 0xa0976747, 0x5e8caddc, 0x2576c255, + 0x37c4b1e5, 0xf8710210, 0x0b0dbef3, 0x1767e4cc, 0x4ca57e6b, 0xdbe91f00, + 0xfa6f7899, 0x36c78a02, 0x56be33c6, 0xc7ee78fe, 0xd6bae12f, 0xa229c5a5, + 0x5e87d61c, 0xfee03e9a, 0xde149710, 0x67d2fce7, 0x0bdf49d2, 0x4857ee5e, + 0x22657871, 0x26e298ec, 0x974cf539, 0x9579e1ed, 0xe6ce9ecb, 0x8083e2f3, + 0x2ad970f1, 0x6f01d191, 0x521e02d8, 0x4520fec8, 0xf2d66df2, 0x1cd6acf7, + 0xd34a5bfe, 0xfc991ee2, 0x9c5faf37, 0xced171c6, 0xc676a7f8, 0x066ff8bd, + 0xf993d5ed, 0x57d13f09, 0x4c66126a, 0x5bb4fb60, 0x328b8ec9, 0xb7701e78, + 0xbdd2cb06, 0xea8f09d3, 0x32ef3635, 0x1c47df37, 0xb181e1aa, 0x5429b54d, + 0xf3c223f1, 0x0b779b4d, 0xbc796dc9, 0xb924ef12, 0x0e7af282, 0xad98c7ab, + 0xa72fb449, 0x76e64ab3, 0x989ffd8c, 0xc1dabfb1, 0x227560fd, 0x15cedbf2, + 0xb7fb84c4, 0xbe4cafd1, 0xf0dccf5f, 0x85f3cefa, 0xb99df8f0, 0x49e4afc4, + 0xdb1e108f, 0xc8af6645, 0x29c3358c, 0x0e2ed96e, 0xf1a64e7a, 0x57e445c3, + 0xc81cefe7, 0x1db2b6e2, 0x617bb21f, 0x56e726be, 0xc7296f2d, 0x33844ef6, + 0xf8bdb832, 0x666ba845, 0xe8bf9e6d, 0xabc7d6f2, 0x9c985957, 0x937fd1aa, + 0xfa5ea8e3, 0xb56fb65b, 0x79469423, 0x961bf556, 0xcb6fe4a1, 0x97cbfc35, + 0x09fd19f6, 0xc5b94fea, 0x543dd125, 0xa95b16a5, 0xb028d55d, 0x6a5d7876, + 0xe7e3e93a, 0x4938f7cb, 0x07c4ce4f, 0xb4df743d, 0x52f7882f, 0xc0da887e, + 0x97cf93ee, 0x873f367b, 0xc85259ed, 0xacf8e021, 0xc89332c7, 0x82949f2f, + 0xd93f1a56, 0x5b5136ec, 0xd4d1a491, 0x62dfcc56, 0x55d1cfed, 0x43fa6b35, + 0xe046a5fe, 0xed7aacf2, 0xcf0335b0, 0xffc9a95b, 0xb30ff6ca, 0xa756cfc9, + 0x397db287, 0x14d9de4c, 0x04cfc2ff, 0xbcd6df76, 0xba60ebc6, 0xde486bbc, + 0x34f35f68, 0xdeecd739, 0x7de924f3, 0xaf3bc90d, 0xdea0beab, 0xaffd611e, + 0xbe022a6f, 0xc5e908fe, 0x53cc7899, 0x05b97b79, 0xbcacc7db, 0xbfe6acfd, + 0xf790bfb0, 0x4f3c39ab, 0xac6b79e3, 0xbe4adfbe, 0x263f244d, 0xa7f31b0f, + 0xadbd1a4d, 0x9270deab, 0x3f6caefc, 0xc1c8eefc, 0x57e61784, 0x5ef44df2, + 0xd12d47e3, 0xb3f864ef, 0xe896a1b8, 0xefe98675, 0xdecd73d4, 0xa7d3816a, + 0xd66b5bd3, 0xb5c7d7e8, 0x3a345bf5, 0xd7e340ab, 0xbedc7eee, 0x7b227b34, + 0xa749fca5, 0xd7c49fcf, 0xbef9faeb, 0x4d6edf46, 0x766a414f, 0xbe487f12, + 0x7f5067e4, 0xcd50eb14, 0x2b94e06f, 0xfcb1373b, 0x8e979751, 0xfbe1a7ff, + 0x0a4c4942, 0x04d5b1cb, 0x5ded9a73, 0x1a23c5ef, 0xe8ad4f1f, 0xfc82de9e, + 0x06f31cfb, 0xbea36e96, 0xd3ce239a, 0xaf3f46f5, 0xfdc95b60, 0x86600eac, + 0x9fafed20, 0x304d527b, 0x81273ed3, 0xbf8e87db, 0xf505976e, 0xe81feed3, + 0x1c5779a4, 0x37443999, 0x0cd3ff3f, 0x5457ad89, 0x4af3f307, 0x7010108b, + 0xebc094e8, 0xec56a782, 0x84e79671, 0x327ffdf5, 0x62ff4e84, 0xa78aeb4e, + 0xfa117fae, 0x782cf0cc, 0xd4fdf276, 0x7a16f4fe, 0xd74df3a9, 0xca9c584f, + 0x3d5893e2, 0xca7dedad, 0xf6c5e74a, 0x19caf1eb, 0xfec97bca, 0x10faf2f7, + 0x5923872c, 0xeeb0f711, 0x0ecff1d7, 0x84f7c343, 0x65e72f7e, 0x2efa3066, + 0x1f35b341, 0x85d578fd, 0xa6539150, 0xf5644fb8, 0x08bfbba0, 0xb3d42e8a, + 0xbceeddaa, 0xeaad7bc8, 0xa7a611f2, 0x756210d5, 0x1f55b2cb, 0x7d230f16, + 0x45c629fc, 0x8c5757e4, 0x3d5c52b5, 0xa1cccb77, 0x0dd3e724, 0xb8badefc, + 0x142bc87c, 0x786e9f17, 0x0e666d21, 0x1a282bad, 0x6b65fd89, 0x9e393207, + 0x53150f89, 0x1171fdbb, 0x6a358ea8, 0x53c590cb, 0xd1ca3db1, 0x39e89137, + 0x8e1624d9, 0x2cfb908c, 0xa54f1690, 0x92eccc78, 0x6a4e0ec8, 0xc2deabfe, + 0x933bd2e5, 0x277279eb, 0xa0bafee4, 0x44db3ebe, 0x7e84db7c, 0xc5aee913, + 0xd507a018, 0xff1e054d, 0x5c42b1cc, 0x1fd63ccf, 0x4dfb13d7, 0x09aa2709, + 0x13c7b6ff, 0x4ddbaa24, 0x883781b3, 0xfb0769ed, 0xa6e851e4, 0xc6287168, + 0x9d5cecab, 0xbdf9fa4f, 0xc51eb932, 0xf5e20bee, 0xc76fa4a1, 0x19d63ab4, + 0xcb8bef0d, 0xee893a7f, 0x3d5b8ba5, 0xf9f74449, 0x140df1fd, 0x70b79cc7, + 0x7fefa57f, 0xd88f77bb, 0x77d88ef7, 0x0c65800d, 0x189901af, 0x6740253f, + 0xe3eba4fc, 0x70baeaed, 0xcdd78d22, 0xfaf53db5, 0x5ecd1ffa, 0xd64de257, + 0x12f2f0e9, 0xce365864, 0x9e083aa3, 0xe5f0985f, 0xd9c510ae, 0x86c9368d, + 0xbd259ef4, 0x86fab6c6, 0x1481eac8, 0x9f9e9313, 0x8050637d, 0x138ab7f2, + 0x2cd15dbc, 0x7884a804, 0x22b3ed64, 0x718d9fcd, 0x2221775e, 0xed717d6e, + 0x6bff5224, 0x9ecaff5e, 0x56daff38, 0xe037bd81, 0x5e263db0, 0xfca7b77d, + 0xf5578bef, 0xe754bffc, 0xa42ef6bb, 0x57cf5bf3, 0x0c5ea20e, 0xedf30bcf, + 0x2c3992ea, 0xc4bcbd5e, 0x709b60cf, 0x5628cd6a, 0xbab176e7, 0x5e5a2fef, + 0xdc917b10, 0x4ebc0f77, 0xbb48e779, 0xbdbb224b, 0x401164ba, 0x63abad36, + 0x5ebb9750, 0xf77bb9df, 0x6aeeb621, 0xa37da0cb, 0xbb01dd70, 0xcee7f98b, + 0xf79892f7, 0xbc58ef91, 0x7dd913dd, 0x7451dfc1, 0xd772ebf9, 0xded4abe9, + 0x2ffc7445, 0xdee5c53d, 0xd33aded9, 0xfa1ef449, 0x11bef251, 0x9704ef24, + 0xb9da7144, 0x5c5fdcf5, 0xf2bd7388, 0xc2fbca20, 0x80698986, 0xa1f6727e, + 0x7f512787, 0xa2417ec5, 0xbfbbdcf8, 0xd3f949c4, 0x4eadcdef, 0xbf7ef3ca, + 0x0abf7f5e, 0x469fe488, 0x3489838e, 0x0cd0647f, 0xe233ee32, 0x2337ae41, + 0x0a039b2e, 0xcfd83bc5, 0xbbd716ea, 0xfe05bab1, 0xfde09725, 0xaf2f7b39, + 0xd072e873, 0x1a51adf3, 0x9333079d, 0xfeb4ff38, 0xffbce182, 0xe35d86fc, + 0x4d8bbf69, 0xbef08916, 0xfb6164da, 0xc93cc3cf, 0x5b33ef44, 0xed421e79, + 0x37d93778, 0x35e637cf, 0x7aa37cf3, 0xbab14581, 0x4167eaba, 0xe7ca3cc4, + 0x73a64fb0, 0xa7fa6ae7, 0x853cedeb, 0xef0f37d3, 0x5637a235, 0x99a1138f, + 0x4edddbbd, 0x3d56ff9f, 0x37e31dde, 0xa982584e, 0xef9f8993, 0x77565e89, + 0xe87e85b9, 0x403f257c, 0xc3ebac7a, 0x0517d43c, 0x079a9287, 0xea3e93e6, + 0x9bfba1fa, 0xa5e35bf9, 0x2dfe51b3, 0xdb5daa31, 0x1b3a53d2, 0x7a69e719, + 0x99823908, 0xe9d2abe8, 0x535d6b8b, 0xf8a6b082, 0xc421150f, 0xafe88473, + 0x9152a4f0, 0xc05e8bef, 0xc69ed964, 0x642091de, 0x061ef601, 0x6a17ff4c, + 0xa2b1b075, 0xe519bfbd, 0xf3742a58, 0x96d93e52, 0x2e4d50ef, 0xf9327796, + 0x04253e96, 0xc44ffb00, 0x9ea9733b, 0x0e420330, 0xbb3fb637, 0x464d7643, + 0xf5ebd5f9, 0x2d63b56a, 0xe65767d5, 0xfffb5a8b, 0x3aa8944a, 0x8afdffc8, + 0x530f20ea, 0xffb5943d, 0xf6f5425a, 0x71b477b6, 0xe3425eb8, 0xab402b6d, + 0xdbc57d8b, 0x85c7d03f, 0xdb5fb409, 0xe45c7d2a, 0xfdf5e7ed, 0x98daf6b5, + 0xe331a5f1, 0x1ff6f12f, 0x504e227e, 0x88f5c273, 0x9ef7b527, 0x7d5a65d2, + 0x8336f4c2, 0x93df2cf6, 0x1d17cf54, 0xe7941d67, 0x27947914, 0x7bf0dde9, + 0xcd7ffd7d, 0x44af3844, 0x9f78ad50, 0xd9026fc1, 0xda75e7c4, 0xe1ffdd7c, + 0xc9bac83c, 0x6f3439bc, 0xcb3cd448, 0xda7de6cd, 0x376ebf75, 0x89e2979b, + 0xe77f4fde, 0x9c56e29d, 0x278f5f34, 0x94afef62, 0x8c471e2c, 0x699254ca, + 0xb40b239e, 0xe9bc42b8, 0x16615a3b, 0xbb4a038f, 0x99b677f1, 0x32711d43, + 0x37e431e2, 0xf9077afe, 0xbe3c0db3, 0x98efb57a, 0xf41fb43e, 0xc757be8e, + 0xcc43ef21, 0x3cb3b5af, 0x86fb8ff2, 0xd1bfc8b8, 0xebaf24db, 0xea9f7da5, + 0x759dc5ee, 0x67dfbea6, 0xacb74def, 0x409df543, 0x5f71a875, 0x66f3bd71, + 0xc93efcf5, 0x01b0da75, 0xb48fc8dd, 0x25effba4, 0xbb0da63c, 0xf9da88bb, + 0xaef662b6, 0xefafa3dd, 0x6b3fea1e, 0xa1089e52, 0x6346fb3e, 0x7f611b20, + 0xa2130a13, 0x983f0fda, 0x3d844a0c, 0x57b87a4e, 0xd291fb54, 0x53f9a8cc, + 0x3515dd67, 0x0d0b6c5e, 0xf69c7966, 0x78ab7cce, 0xc61df3a2, 0x9f3debc1, + 0xc7d3fbed, 0x6a1fa28f, 0x5d59126b, 0x2dfeee77, 0x70828f1f, 0xec46805c, + 0x74bdfb22, 0x93ca044c, 0x5757eb63, 0xb46eb420, 0x80f135f0, 0xe5c58474, + 0x8d1fa8ff, 0xc6a34bc8, 0xfb4567a7, 0x1f756bd3, 0x23180ba5, 0xac7568d5, + 0x594f7b2b, 0xbbff5e65, 0xeafd0371, 0xde90b47d, 0xfe903b3b, 0x2d7fa841, + 0x38adaca7, 0xe64b23de, 0x05ef4779, 0xe5007966, 0x4acc0b11, 0xa1171e84, + 0xbea8b81d, 0xde3f71d2, 0x83474878, 0x74d7d6c2, 0xb8bb5898, 0x5465b4d7, + 0xc336aa6f, 0xc754dd80, 0x6e2c1d90, 0x7df9fe2a, 0x67e580e3, 0x63f74282, + 0xe7c2a355, 0x4c1ebf8b, 0x1db1b0f5, 0xc53ed8e3, 0x50131c22, 0xe0281f37, + 0x31d5d17e, 0x76d7f581, 0x6e0f9b00, 0x54ace2ff, 0x7144aefe, 0x29aefe6f, + 0x72888985, 0x86795bb2, 0x2297ebf4, 0xfbbb222c, 0x86f7bde5, 0x5f7a1494, + 0x32283418, 0xc59358ff, 0x6a400ddf, 0x5df74ebf, 0x990481ed, 0xc5eac8e4, + 0xb7ed0f14, 0xec7c77b1, 0xda90f567, 0x94cdb603, 0xdb3ad5e7, 0x0afec9b3, + 0x8907c60e, 0xe307438e, 0xcdbf2ccd, 0x73a1aff4, 0x2bf60e0b, 0xd9537ca4, + 0xf3033367, 0x98f7ca63, 0xca589e3d, 0xd25d3ae4, 0xea37fb04, 0xbfbf6c63, + 0x4cabf381, 0x872ebbe3, 0x7eef8d72, 0x1a659f8d, 0xdf1067df, 0xc5f2ee91, + 0x587b6fc8, 0x29a2c52e, 0xb260fd7b, 0xca5e3e8f, 0x15bf743f, 0x8eaaf7cb, + 0xeaf7c638, 0x7c9a1e8e, 0xa1c945bb, 0xb58323bc, 0xdb7dba07, 0x7ae2ce89, + 0x5fee2f94, 0x287a0f6e, 0x17519a3f, 0x87f7a5ef, 0x45dd8b6b, 0xab85d7c4, + 0xfee6e1b0, 0x8ab5ee8b, 0x74add4df, 0x4a65c844, 0xb8c82e47, 0x2c8ec4df, + 0xebed5f06, 0x2e724bdf, 0xcecf18eb, 0x66c8ef29, 0xa95c62e7, 0x23fef8b0, + 0xfbffbe3d, 0x20b9c7be, 0x21811b30, 0x75dfca8a, 0x26ef3602, 0xcbfdfc21, + 0x54238c4c, 0x1696673c, 0x5b650e7f, 0x6c9b7f22, 0xf8424381, 0x72ff18fb, + 0x9da86a91, 0x3be5d7f6, 0x678c7c99, 0x26e5dd70, 0xd543930b, 0x950f5fa1, + 0x9092fc70, 0x4eec9ddf, 0xc47ff24d, 0x810995ee, 0xcf6c161d, 0x73977e7f, + 0x8fd61c84, 0x43d07366, 0xf919a67e, 0xe6b5f548, 0x00b8e2d5, 0x942667af, + 0x9eb5b80c, 0x83b8ebcc, 0xb79febf1, 0x286b4dd3, 0x66cb869f, 0xed879796, + 0xb78ef375, 0xb8127f48, 0x6ecadcfe, 0x58912cf7, 0xbf6b167c, 0x959eddba, + 0xf9227ffd, 0xcfadbbde, 0xfee11fe0, 0x584a5363, 0x99ef1cbd, 0x87583ca8, + 0x7f31eec9, 0xb3b7f9a1, 0xcac7bb6f, 0xcf6b12f8, 0x6db37d7a, 0xb2019dff, + 0xf68093f7, 0x2fb47a4f, 0xd9a2de41, 0xdd07f33b, 0xb3af815c, 0x339951f7, + 0xddef14ed, 0x9e1ddec4, 0xdece6fd4, 0xf23939bf, 0xf85201bc, 0x1c846afb, + 0xa43d50d7, 0xc9852db8, 0x2e9b9751, 0xba7e5d47, 0xfd963ebc, 0x637d1177, + 0xd775fdb6, 0xd55762ff, 0x53073deb, 0x793b767c, 0xfee1e3dc, 0x8f285ff6, + 0xf7373c7b, 0xfe7af7bf, 0x7e8bff09, 0xe26ec072, 0x5bc3a64f, 0xa3f9872f, + 0xb741e3cb, 0x2433d8bf, 0x68241fcc, 0x6f4fd530, 0x9ee98fc7, 0x99fefc6f, + 0x67fa0b7e, 0xfff433fc, 0x1292f9c3, 0x78b12f9d, 0x49e50466, 0x5527963e, + 0xfc83bd53, 0x4fe818df, 0x15bd59f1, 0x9aa43e58, 0xee4979ba, 0x42d97625, + 0xc5259771, 0x3afd216b, 0xbea211ea, 0x48f56bef, 0x2496087d, 0xbd0ddfe8, + 0x128cf2cd, 0x43cb4997, 0x30f6f30e, 0x09bdfc7d, 0x0c94d794, 0x18e1c6d2, + 0x6c089f1f, 0x472df9fc, 0xcdb25e59, 0xfc20aca3, 0x4c48f05e, 0x74b7173e, + 0xfde7e3ef, 0x5747c40d, 0x04bbffb2, 0x5676ad6b, 0xda136b4f, 0xc3b91773, + 0xdfb57ff3, 0x8817f271, 0xaca3c877, 0x502f79a1, 0x12352231, 0x16ad79f2, + 0x84e6f748, 0x5601cbfb, 0xae58bdd0, 0x6044fd1e, 0x1c3c1df1, 0x1fbe9437, + 0x959f7604, 0x35b1dfeb, 0x06c77f44, 0xb3e3175e, 0xfea11dfe, 0xb09de09d, + 0xd7bed25c, 0xf92370db, 0x866ce4eb, 0xafdf1173, 0x2e9059b5, 0x22efd757, + 0xff477d85, 0xabd6fb42, 0xf2cf1ad0, 0xd7efe8d9, 0x4f3013aa, 0x7b287e45, + 0xca3b411c, 0x04f6e171, 0xab986756, 0xa47b8fd7, 0x31f44bb0, 0x3d03d389, + 0xfd7dd8d2, 0xe74ba6b8, 0x2cff4097, 0x6fcdc533, 0x1e23355f, 0xeff1f66f, + 0x99543925, 0x285f483e, 0xdea45d53, 0x95d0f749, 0x4a97a21d, 0x9d5a5530, + 0xb5529a1e, 0xbc188afa, 0xb98fc717, 0xf54cdcef, 0xfe1ec3bd, 0x0dd9714e, + 0x5d519dec, 0x10b6936a, 0xa70fd72e, 0x71ed8d3f, 0xe979f719, 0xcef2eefd, + 0xa366b367, 0xc05ad01c, 0x00fae2c9, 0x36c1675b, 0xd2b91f7d, 0x96ba42fd, + 0x4220fbbf, 0xbb9f3a1e, 0xa28f1ff0, 0x0e29bdfa, 0x09dede98, 0xc78a241b, + 0xa58c3975, 0x838a53c7, 0xc8efe0de, 0x6ce8050b, 0x3e725c53, 0x5dfbe78e, + 0xb0ef8beb, 0x52cd017c, 0x6cdbaa8d, 0xfcf37998, 0xa5602522, 0xbae9bfad, + 0xf68f25e3, 0x06103e4e, 0x791deff2, 0x9b52a35d, 0x952c5633, 0x6a4f44cd, + 0xbfe4979c, 0x77666370, 0x7c3043f2, 0x83ce441d, 0x2f4cc90d, 0x1845ba56, + 0xb7367a8e, 0xfba4c905, 0x160ee5a8, 0x92d83df7, 0xe313a0c4, 0xf8bfea4e, + 0x7983fbca, 0xa7cb871d, 0x63eed5f8, 0x6afb1c58, 0xf563063f, 0x4fb9fcd6, + 0xd84b77a1, 0x123ab023, 0x75ca12f9, 0xc7563d75, 0x6eac8378, 0xeec096f7, + 0xbf9b293d, 0x75495463, 0xd20e1dec, 0xc22f2c7d, 0x2ec94b25, 0x6cddf45d, + 0x8faeff12, 0xf7dacce5, 0x3e4d4eb1, 0x7df9d009, 0x881bef6c, 0xccb67277, + 0x3d208bbf, 0x264949c1, 0x5cfc9bb7, 0x393fb66a, 0xe6bde29b, 0x9f54459d, + 0x4aea0b9a, 0x13d94770, 0x6ae848dc, 0x77b497a7, 0x2b0f5d31, 0x852173b5, + 0xc6855feb, 0x3e8d4ad6, 0x2b5418cb, 0x4772cfa4, 0x377ae6f6, 0x80fe8691, + 0x1f0adf7d, 0x40fe3dfc, 0x3f7407bf, 0x2cf535fd, 0xc7d2cfc6, 0x7ce3ddb9, + 0x0ffd175e, 0x511f5021, 0x6faceac7, 0x77b0233d, 0x326ebd6d, 0xbd0a0ccd, + 0x095422ef, 0xd2f7d296, 0x8598e104, 0x62e38b9d, 0x8cc3ab12, 0x63ebfc62, + 0xd39d5952, 0x9830ebce, 0xfd43dc27, 0xbf66ead7, 0x7920f8cb, 0xc51bf7d9, + 0x6c4f5e36, 0xdf644f7f, 0xee8add1f, 0x555e5af1, 0x6f62e07b, 0x5f71dbb2, + 0xf7e27e89, 0x11e38b71, 0x67c753ca, 0xf197f7f3, 0x9828a6d9, 0xe98bfb2e, + 0xea3b3fdc, 0x5f909ba6, 0xc167be7f, 0x8771df2b, 0xae887ae9, 0x40a7ba2c, + 0x4d3e90b6, 0x371de504, 0xf06df56e, 0x5064f6b3, 0xf7496c19, 0xa54eca4f, + 0xac0310ef, 0x7dc47c7d, 0x8b125eac, 0x655e2c7f, 0x2c5efcd9, 0xc14536cb, + 0xcfdfb271, 0x5e1852f1, 0xd1365fb8, 0x24f5e3a5, 0xdfea4ee9, 0x88555f25, + 0x7ccaef90, 0x02d7df91, 0xf2c3afbf, 0x25496b1d, 0xbd108ef9, 0x0c17ab4c, + 0xe0f48479, 0xa5eadd9a, 0xbe5d3b77, 0x9bde8108, 0x638e72c3, 0x88ba52fa, + 0x6c91cbeb, 0x6a0baf37, 0x580e4772, 0xf942ae28, 0x9a7c4d3f, 0x75e44237, + 0x3fe50938, 0x4addc980, 0x82995e36, 0x2ae8cf72, 0xde2d5adf, 0x66e2d1ad, + 0x66f51fbd, 0xeae9f105, 0x89fd61de, 0x4607b53f, 0x7a9fc4c8, 0xd4dbcf13, + 0xd0ead6ff, 0xa38bc99a, 0x47ef62ee, 0x297af660, 0x45be2aff, 0x9355b29e, + 0x961ef1cb, 0x5fb60171, 0x4076bbf4, 0xa6809fd3, 0x9c70ff57, 0xe2a21fd5, + 0xffa211ac, 0x754fe265, 0xf32b55dc, 0xfe7bda63, 0x19b37a56, 0xd11fd612, + 0xb26ff0ea, 0xf5cbe247, 0x55f9f506, 0x44e7ff5a, 0xa64ce7d4, 0xef28e7cf, + 0x75e56e3c, 0x156456e7, 0xff107ffd, 0xccbbfccb, 0x3e9a77f0, 0xbc512b06, + 0x8042e704, 0xbad0f9c1, 0x9fce1072, 0x469658d8, 0xfc9854f8, 0xa2ad3eec, + 0x3be9bc2f, 0xec2f681b, 0x76fcfc81, 0x7a77d2c3, 0x5e538a20, 0x5c285b74, + 0xb041b49b, 0x97be40f4, 0x41582d34, 0xb78fb46d, 0xb70f4e48, 0x0ee77a6c, + 0xe39d17ec, 0x8f1c7d98, 0x1cac5391, 0x45fc6b0e, 0xd39b787b, 0x70ba30a5, + 0xa1ed4dfd, 0xe12bdd06, 0x01ffffa5, 0xd5b93efd, 0xefd023ff, 0xe3781b15, + 0x7a6ec8e2, 0x3fbfcc83, 0xf3e7f68f, 0xfa27df80, 0x923afa7e, 0xf397dd20, + 0xf4979ba1, 0xfb8592ea, 0x807d4bcd, 0x0125c1d9, 0xf0bcec2f, 0xfee906fd, + 0xe199791e, 0xf4d6a37b, 0x39f92e5a, 0xc77e57bc, 0xe699e2fc, 0xe4dd0395, + 0x64e903ff, 0xd99f96af, 0x735ff5bc, 0x9510ccbf, 0x80ceb4d3, 0x01a03406, + 0x0340680d, 0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0, + 0xd01a0340, 0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d, + 0x0680d01a, 0x0d01a034, 0x1a034068, 0x340680d0, 0x680d01a0, 0xd01a0340, + 0xa0340680, 0x40680d01, 0x80d01a03, 0x01a03406, 0x0340680d, 0x055ff01a, + 0x328d1fff, 0x800060f6, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, + 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4, + 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00, + 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4, + 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00, + 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4, + 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00, + 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4, + 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0xee017e3f, 0x0014ab55, 0x000014ab, 0x00088b1f, 0x00000000, 0xc5edff00, + 0x30001131, 0xee300408, 0xd80ea5ea, 0xabdef271, 0x964d2104, 0x5dbbcce4, + 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, + 0xee017e3f, 0x0014ab55, 0x000014ab, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x00088b1f, 0x00000000, 0x62f3ff00, 0x51f86063, 0x408cc10f, + 0x7f120cb6, 0x66476028, 0x48107d08, 0xf3e2061f, 0x2fe9a48c, 0xb9b04160, + 0x40afec80, 0xa8597833, 0x88a1bee7, 0xcfd2738f, 0x81ae792e, 0x66322ff7, + 0xe86067e6, 0x6ff047e4, 0xb3caa3f2, 0x3dd7d3f0, 0xb000c6b4, 0x00eeff4a, + 0x0000eeff, 0x00088b1f, 0x00000000, 0x7dd5ff00, 0xc554780b, 0x3d9cf0d9, + 0x3764dd97, 0x2485cd9b, 0x200d8410, 0x125c40a2, 0x126e20ee, 0xc3116088, + 0x65e28145, 0xb201ae41, 0xdb3f6911, 0x5cbb7ffa, 0xc6d6a444, 0xa0b45b4b, + 0x06a2828b, 0x82482459, 0xa5c8ba1b, 0x5835b5b4, 0x0da978aa, 0x24c4dc88, + 0x97f4b004, 0x3bef3fca, 0xce7bbb33, 0xf4bc4c6e, 0x7d6f9ffb, 0x7339867c, + 0xef3bccce, 0x6779de7d, 0x313b10a2, 0x0ae42775, 0x64246efc, 0x19084c99, + 0xbbc32d14, 0x32413cbf, 0x46bcf909, 0x08f39a75, 0x86a1d929, 0xc5f5a46f, + 0xd400a41b, 0x0893bb4d, 0xd3484819, 0xcaf7563a, 0xa08e8f0d, 0x4ca764ed, + 0x8482d136, 0x4592266d, 0x610b09c8, 0xd60a673f, 0xeab126e7, 0xee7b0de2, + 0xd7e7fe82, 0xfd12499a, 0xec8d44fe, 0x4d92fa86, 0xb4488052, 0xad21eebd, + 0x5e7fed0b, 0x39260a40, 0x63d37d69, 0x9085339a, 0x6cbfbbe5, 0x5c057182, + 0xe2167c67, 0xbfbe00d4, 0x23f63565, 0xadb03ca4, 0xa7ed0bb4, 0x99725abc, + 0xebe538e8, 0x038df0a4, 0x9014b9e1, 0x370bbf69, 0x0fb3895b, 0xc10ae183, + 0x4b1e7171, 0x6971d3d6, 0xd2a9447f, 0xe3a252ca, 0xf19cfc09, 0x4471c5ad, + 0x744bf17d, 0xc55dfa1c, 0xa60b92ab, 0x9e226158, 0xa9bf1d20, 0xf3da692e, + 0x32df9836, 0xec4a77ad, 0x0ebe663c, 0x6c0f28f3, 0x006d4ad0, 0x6e6d06d7, + 0x0b7f68bf, 0x0f56ff37, 0xd99edad7, 0x6376989e, 0x5147c679, 0x2f5a3bda, + 0xb41dc427, 0x6d01fc01, 0xf3e8ff62, 0x908d295a, 0x4cbfd04e, 0xff68969c, + 0xb9f1f884, 0xc0615c4c, 0xb8a5093b, 0xead6e962, 0x496dd3d0, 0x0db6ff1a, + 0xe9c97e78, 0x81cf98f0, 0x1cbe13e5, 0x73e57f2c, 0xf1bf9c22, 0x29f2c1f5, + 0xff9f0b9f, 0xcb1437d6, 0x96373ef5, 0x62c6facf, 0x8657c1b9, 0x9bef3def, + 0x9f26e586, 0xe8bf9f07, 0x4be58f9b, 0xfe7c4abe, 0x2c7eef8a, 0xf8fcf8b7, + 0x356fab7c, 0x557cdb96, 0xf4e76e58, 0xe00be1da, 0x9b7d3b7b, 0x05f3acb1, + 0xbe1bf9f1, 0x017f2c5a, 0xaa65a478, 0xa14cb1db, 0x4d1d4a74, 0x484d941c, + 0x32d95946, 0xa633d695, 0xa7b67ab0, 0xf146996a, 0xd69b3d94, 0x2b731d29, + 0x6999961b, 0xd652ee7b, 0x58efddde, 0xddeda16e, 0x9ef6b257, 0x93cb6555, + 0x27cf7b68, 0x8135fb59, 0xb4c9e5aa, 0xac8d9afd, 0x61b06fbd, 0xf7b695b9, + 0xd7ed61ad, 0x6c2b1d87, 0x3efd7eb4, 0x286c2f56, 0xeb42915b, 0x7d598785, + 0x0ad56348, 0xc87efd3b, 0x88fdf671, 0x4ceca096, 0x55db1fc0, 0xd2843dd7, + 0x52fed7ee, 0xd68c32b7, 0xc47dd735, 0xff66c845, 0x33a56ead, 0x865a87c5, + 0xd3fcbbed, 0xc32b5d58, 0x33fcb7f6, 0x6a9dfdf1, 0xec7fb625, 0x9df6c72f, + 0xb7b6255a, 0xf6c3eff8, 0xdb0ab53a, 0x601ecb4d, 0xdb0aad75, 0x883d9733, + 0x52a1bfef, 0xd2138760, 0x6ea3d97b, 0x966f853f, 0x7d02a9e4, 0x9caa6cd2, + 0x28b7404f, 0xaf901ce1, 0x0d322487, 0xc4a7e5e4, 0xa1e6fa89, 0xc83734ab, + 0x8343f6e1, 0xc539079f, 0xe7d4265f, 0x0f26b0be, 0xfb0a79fb, 0x3d3f68d1, + 0xf0a7efdb, 0x7ebaa19d, 0x2f99df0a, 0xf80e79fa, 0x63b939be, 0x677f6cfd, + 0x779e1eb8, 0xaf3f45ca, 0x8ef63f60, 0xaff0abcd, 0xfcf0f523, 0xa7e89175, + 0xde95e706, 0xbc767831, 0x1793f14f, 0xfbc767ed, 0xf6123f14, 0x64fd8f53, + 0x419e0c75, 0xf5d50c1f, 0xf983e833, 0xd8039fa2, 0xf58e974f, 0xe183e3b3, + 0x283e787a, 0x8dbcfd17, 0xd8eb74fd, 0x387d06bc, 0x87cf0f52, 0x473f448b, + 0x1d1e9fb0, 0x51e767eb, 0x1e767e3d, 0x28e7e08d, 0x63bbd3f6, 0x4c721af3, + 0xc7219f8f, 0x8339f822, 0x63aebf74, 0xa63cecfd, 0x63cecfc7, 0x479cfc11, + 0x363bf278, 0xe89f21af, 0x93e433f1, 0x632e7e08, 0x831d053f, 0x1eb4eea7, + 0x23a7753f, 0x982551f8, 0xc18ee0d7, 0x1e8cec33, 0x44cec33f, 0x009763f0, + 0xeb1de19e, 0x1e8ceea7, 0x2267753f, 0x7846c9f8, 0x5e6c7546, 0xe3d33ec3, + 0x1167d867, 0x9e1138fc, 0x08cdcae2, 0xf4fda10f, 0x379fbb6f, 0xcff5e9ce, + 0xfe98e71b, 0x8fc47819, 0x21cd57fa, 0x6467002e, 0xa25f994b, 0xd6932575, + 0x89ba509d, 0x055fda87, 0xf83f70ec, 0xd32fd1b8, 0xb4ea94f6, 0x58ce3582, + 0x02ec5c7b, 0x4d03ec78, 0x18ef7b3a, 0xa7abac99, 0xd9d74e8f, 0x5df1cceb, + 0x29acf574, 0x9cf5743d, 0x7dd3ae3b, 0x817665df, 0xd175deae, 0xdbbd5d70, + 0xf7dd62d2, 0xd66e07ce, 0x3958f7b5, 0xf5ef5749, 0xf5750fc8, 0xd2ce4fde, + 0x2bacfbd5, 0xdd77f5d7, 0x7aba25c6, 0xea9feabf, 0xcb35f9ea, 0x68577575, + 0xb05eae8d, 0xff5d71ef, 0x5a7adf03, 0xf87c1f57, 0xe87d5d39, 0xbeeb2f47, + 0x35fc7e1f, 0xd9e47d5d, 0xc7ff065d, 0x97d138e6, 0x77f065d7, 0x9a07e8ad, + 0xcfe869bb, 0x60b37516, 0x6cddc7fd, 0x28f1ff58, 0x4a0e35cf, 0x07c39fd7, + 0x58fdeed4, 0x48ef5cf3, 0x25297f60, 0x4a07244d, 0x8d0c898f, 0x52ad5f6f, + 0x527ca3be, 0xef72fddc, 0x9af4b4a3, 0xd1a77a5a, 0xa2a6eff2, 0x3f17c0a5, + 0x97e84c95, 0x09526559, 0x1335647c, 0x57d5cbe4, 0x1fde7e0f, 0xe70fdfc3, + 0xfd14be31, 0xe656ac3e, 0xeffe1d80, 0x83f3bf65, 0x4f287e1d, 0x93ec3b43, + 0xf7f6177e, 0xfde7dfa2, 0x49fc0738, 0xd4fd468b, 0x3a35f1d8, 0x7f1c3f7e, + 0xa6bf8c25, 0xbd2df18d, 0x4fc6ea87, 0x375f31ea, 0xc746927e, 0xe8f21077, + 0xf1f3dfb2, 0x50bafe29, 0x3dfa50bf, 0x71e96f8e, 0x5abf8e3f, 0xe375f323, + 0x7fc64727, 0x69fde412, 0x82507f18, 0xae1ef7f9, 0x728f7f9f, 0x3635fcfd, + 0xbd9667ff, 0xc64fc7cd, 0xbd2b3ff9, 0xe3dfe6cd, 0x66fe6ca7, 0xf8ec6fda, + 0x37fe08f6, 0xb72ff8c2, 0x9ae5be31, 0xf7f9fa91, 0xbf9fa45c, 0xeaff8d99, + 0xf8f8f7b2, 0xab7f1c36, 0x7f9b1ef4, 0x7c7007cf, 0xe5d2b9b3, 0xeee64da0, + 0xd00195c9, 0x263dd413, 0x746020d9, 0x2820219c, 0xefd084e9, 0x903d4817, + 0xa64e3f0e, 0xffdf477c, 0x1bf29922, 0x6fdcf7f8, 0x12558127, 0x1dd74c19, + 0x5767a79c, 0x417ed4cf, 0xcb5d993f, 0xae8433d6, 0xf0a6ae77, 0xff9ed535, + 0xef0a43e2, 0x50038dec, 0x274e514f, 0x3e1cddf0, 0xf0ccaf15, 0xb7594841, + 0x12bf5489, 0xa4dbaca5, 0x06e4d8fe, 0x411e7fbf, 0x78f8e318, 0xa27a954e, + 0xe6fe4631, 0x17d7d5ad, 0x0175f404, 0x09301177, 0xa4c5fd2d, 0xf71d254f, + 0x10275d18, 0x447f97ea, 0x594270fd, 0xdc9513f6, 0xf2f1465d, 0x404f5d31, + 0x27ae91bd, 0x4cae9da0, 0x14c72e91, 0xb63bf382, 0x7a001ada, 0x0193f17c, + 0xbb87d81a, 0x1bf2a7ef, 0x727edf2b, 0x5fc28738, 0xd339e7c6, 0x076fa19f, + 0x4c3c53bc, 0x0b2bf3e4, 0x974f1e2d, 0xd59ee4c4, 0x459954b9, 0xf24a6bdf, + 0x54ffd0a8, 0xe9b356e2, 0x9d2e7778, 0x5f107aa8, 0xca135cee, 0x5135c939, + 0x56e89f39, 0xf4c6358f, 0x8066a93f, 0x93227b4a, 0xdf9feac7, 0x37afa656, + 0x44d56ea9, 0x5134d3e9, 0xdda81b22, 0xdf4d3a99, 0x2339c62e, 0xc5fce3a5, + 0x6e746578, 0x9e61d39d, 0xeffa63f4, 0x3cd83a1f, 0x34bc3ae8, 0x3f73d617, + 0x689b5c90, 0x57bc2a7d, 0xa83d7400, 0xb769f3c1, 0x90d6b9a4, 0x92897878, + 0xe11cfd83, 0xca23bceb, 0xcd0c5fa6, 0x83ff878b, 0x29b756dd, 0x461e7e3f, + 0xa093a7b8, 0xba76f60a, 0xc67cff47, 0x18fce37c, 0x74e09c5f, 0x407c063e, + 0x07c093cb, 0x39c7cf14, 0x2bf5441f, 0xc01383e3, 0x4eb09907, 0xa7307c66, + 0x6ffd312a, 0x479ff4e7, 0x29676afc, 0x9ca9f74a, 0xba73b7ee, 0xe7ab5bcf, + 0x3cf9b88f, 0x1cc1e1b9, 0x3cf98267, 0xa62547b2, 0x657979f8, 0x2ff91f06, + 0x8e89b029, 0xbea5677b, 0xfd0376fd, 0x777e9c3c, 0x7165e846, 0xbf3e5197, + 0x011927eb, 0x7c7133d0, 0x31f5e9c1, 0xb5b4d7a7, 0x4cefed8f, 0xe46be1e2, + 0xf6b13af4, 0xfb44d579, 0x112f9c6b, 0xf08c6ff0, 0x9bbbe11a, 0xdfa03438, + 0x9febf7dd, 0xa627f4cf, 0x28b6b79f, 0xf3cc78e3, 0x1971c1c5, 0x68e463c7, + 0xba89e6e1, 0x74c082fa, 0xd6f3fbdd, 0xcfb5d4ce, 0x6ba05aa9, 0xbdf567bf, + 0xff4cfaba, 0xdfef744f, 0x5d32ff7d, 0x0f959dfb, 0xcc67daeb, 0x9f574c7f, + 0xf74a79ee, 0x1b69d4fe, 0x95b7ed74, 0x9f6ba4bd, 0xae9b763c, 0xa75dd13e, + 0xbdda5f7b, 0x9fc43ba0, 0xd9e79abc, 0xbd9b886c, 0x49cf266f, 0xe84c7af1, + 0x273ee3bb, 0xebe13f3e, 0x9f29e583, 0xf19f9f0b, 0x1972c50d, 0x176a71e8, + 0xf4ac754c, 0x3bb33e3e, 0x07217fe8, 0x6eaea89f, 0x7a8d3fa0, 0xc4e7a8cf, + 0x46bd46fb, 0xa7e0b97f, 0x59cf15b4, 0xb0329124, 0xf312cd0b, 0x43f3c457, + 0xb2123edc, 0x1a45cb1c, 0xaf45d393, 0x39062e75, 0x7b85a45a, 0xeedada57, + 0x9c250497, 0x9eaa9ccf, 0xade7383a, 0xef806bed, 0x05abe439, 0xf3dd4281, + 0xe8479b85, 0x47bb3bbe, 0x402af846, 0xff8187b6, 0x04deb65d, 0xb7bc31f6, + 0x00fee4db, 0x1319fbaf, 0x09db5bc0, 0xdf59eaed, 0x0ae38cd8, 0xcb0cb9e0, + 0x5869be53, 0xb079f09e, 0x8f9bee3c, 0x255f31e5, 0xfbbe8d96, 0xe7d8fcb1, + 0xdf23f2c7, 0xf03f2c6a, 0xc4796155, 0x77cb16b7, 0x0f2c017d, 0xf96336fb, + 0x65882f8e, 0xcb16af83, 0x4b1b9f26, 0xfc312f21, 0x0c73bdd2, 0x277d08bf, + 0xce29e1f4, 0x5f80672f, 0x73c5f112, 0xa938be7a, 0x185f2256, 0x0e91a1f5, + 0x6df77d46, 0xf4dd21f9, 0x9443f0fd, 0x7a06b9de, 0xde8f6cf7, 0x397d221f, + 0x0e4dd3bd, 0xf7a70f06, 0x45780623, 0x041281a9, 0x7e6665bd, 0x595b711e, + 0xabc453dc, 0x7b8b3249, 0x337578f2, 0xbc0377fd, 0x10fb04a7, 0xbf6b5fda, + 0xe21bdbff, 0xcc47adcc, 0x3db5e484, 0xdafd233f, 0x9bf103c4, 0xc9ff0ebe, + 0x14af0cc9, 0xda84b1aa, 0xbed73587, 0xeac59aee, 0x423b010a, 0xb8d8ae82, + 0xc05fa46f, 0x78fb7665, 0x7f31374d, 0x6657bad3, 0x776f08f8, 0xf2894e4d, + 0xd2dcd7ab, 0x95f833bb, 0xd8099a1f, 0xe9b01233, 0xf5a7e5f1, 0xb57c51c1, + 0xf4f68f35, 0xfc2fffde, 0xda8fa7b4, 0xa48743d3, 0x735fc7af, 0x24f75d31, + 0x008e2f58, 0x6df41c3e, 0x1ba1b0f8, 0xf81061f0, 0x5adff69d, 0xe92a4d73, + 0x66e7ed17, 0x13af9393, 0xde4e9ebe, 0xd37e0854, 0x1334537e, 0xcbae9eb9, + 0xf24dcf65, 0x5dcff020, 0x6f4a7e8d, 0x6bab6eff, 0x49d61385, 0x7612fe67, + 0x75fa17c2, 0xe7c1eb73, 0x59aeb0ed, 0x1c726392, 0x3e9b6c2f, 0x0e79838b, + 0x547fac5b, 0x56b7afab, 0xdc596349, 0xa53a99c4, 0x8769e83f, 0xd02f78e3, + 0x8a58399b, 0x68e4967e, 0xf019e38e, 0x79c9805e, 0x81ea1a75, 0xbe0b3e33, + 0xd1c37df7, 0x38513f56, 0xf427c86a, 0x2b89107b, 0xbf7edb3d, 0x2e56be4d, + 0x228f1068, 0x580bf521, 0xffd1252f, 0x7e80f4af, 0x7e8bac15, 0x6fd941bd, + 0x579e1ebe, 0xdfa3c6eb, 0x1b1ec539, 0xfcb6d77c, 0xe084e428, 0x3f374a5f, + 0x2fb8a7f8, 0xfbd0e494, 0xbaba696d, 0x43b3b6b7, 0x3fc1c7e7, 0x2d1cd1c0, + 0x8b47c029, 0x2b355b38, 0x8512d5b6, 0x322c066f, 0xf6259f81, 0xa34b62de, + 0x968fa1e6, 0x7f4148ec, 0x7c63c978, 0x1a4fcd9f, 0x4359fbe0, 0x29970779, + 0x51fd3154, 0xb44c470b, 0x89af0f7e, 0x3559aefd, 0xff5fd10b, 0xdd71f894, + 0x1aae5a77, 0x796a7e0c, 0xa6e68370, 0x989cfb74, 0xffbe82c6, 0x2f63bc9c, + 0x57b7918c, 0x7be70d64, 0xffbd6acf, 0xbab1d74a, 0xeac75d3a, 0xa4c973ea, + 0x9a17d82c, 0x974aa4fb, 0xd5aeb8d4, 0x7656ffb5, 0x91e77ce0, 0x876055ca, + 0xbc29a93f, 0x71e0047d, 0xb0c1fae7, 0x9b459c4e, 0x29fea973, 0x03487cdf, + 0xe3a6f939, 0x0bef802f, 0xf315c7e2, 0xe407db8a, 0x59bc5878, 0xd8120772, + 0xf76e5abd, 0x3bfa5e84, 0x1eb31fc0, 0x23e7cd3f, 0x3f9adfea, 0x65c32932, + 0x4339e945, 0xc1921cf6, 0xa49f008e, 0x5be2f946, 0xd7139ff7, 0xd7bfdfff, + 0x1d12bbfe, 0x4ffed37f, 0xdefc5e83, 0x0715effa, 0xf044c5ff, 0xb22c3a0b, + 0x17c01c34, 0xbe096e1d, 0x14dcb853, 0x7c60714d, 0x725ab9aa, 0xc4fbe999, + 0x2c8e9c4d, 0x3d601fa6, 0x6a5afcd9, 0xe1bd413e, 0x1f3a6e20, 0x552e7f2b, + 0xd123d9ef, 0x3b4ae175, 0xfe51a771, 0x9953e954, 0x692ad1ca, 0xe5a24580, + 0x7f739ae2, 0x9bf68379, 0x88099214, 0xa1853374, 0xdd97f701, 0xac776069, + 0x03b411e4, 0x257ec7b0, 0xd1a70a23, 0x0578103e, 0x8d8397ec, 0x61b6463b, + 0x9d75a6fc, 0x9955718c, 0x919bf75c, 0x0f782f54, 0xeda2f952, 0xb405f0ad, + 0x5d7095af, 0x04b07adf, 0x24eaf3eb, 0x6beb4192, 0x60f9ec93, 0x26dcd2af, + 0x63373c5d, 0x4e7e3eac, 0x5806eefc, 0xf3e6cfff, 0x1c00c405, 0x53bd790b, + 0x7de1ba59, 0x5c4c5ffa, 0xee67b66c, 0x93f14278, 0x771f4d3d, 0x723f285f, + 0xed3ae200, 0x06ed6dca, 0x9463900d, 0xf59b85db, 0x21b78175, 0x09e64a4a, + 0x6236c9b0, 0xadb5bc03, 0x67c1dbc7, 0x8cdfef63, 0x7c71d81c, 0xce64f11a, + 0xc935e3d1, 0xb5abc7a9, 0x066f018f, 0xf4b8a6bc, 0x3a66a2f8, 0xa9af0890, + 0xfae87b43, 0x7af1bef9, 0x6fb3e017, 0x57f49f14, 0xa262c966, 0x56767007, + 0x46ffc8c2, 0x85b5c979, 0x55f7f825, 0xf8658199, 0xf5052b95, 0x5f870e40, + 0xb3becd9a, 0x60c8bc82, 0x2f285d55, 0x3b046910, 0x391f256e, 0xf2268e80, + 0xb7d2b909, 0x37de3a6d, 0x59d1df71, 0xc075abf4, 0x1f23d7cf, 0xe9fc5d20, + 0x0f22b024, 0x00e5d1e4, 0x59f416bb, 0xbae9b39c, 0x711f55f1, 0xcdfea6ce, + 0x96073e6b, 0xf7b0168f, 0x0091fb9b, 0xe1831bac, 0x884e590b, 0xeba1cf67, + 0x1fffaa34, 0x80265ad5, 0x9517fc3f, 0x55eecfad, 0xab772c35, 0x47ffae26, + 0x79f201ff, 0x00ffa99a, 0xd0e6a5f1, 0x50d5cb26, 0xbf3195af, 0x75569bc0, + 0x14df8c2d, 0xb35c1952, 0xf64f182d, 0xc768abd6, 0xc48f669b, 0x9f311a7c, + 0x163c90a6, 0xa1cdd9e2, 0xc4f7ec4f, 0xdaa69dd8, 0xbb05ae27, 0xb12994f7, + 0x628cfbff, 0xc87e6efa, 0xfa3d38ba, 0xf509d28c, 0xe83da3e7, 0xb6262a3c, + 0x9becbf22, 0x77ce337b, 0x9a724847, 0xf2a5dc29, 0x0fe83f1d, 0x537f86fb, + 0xee24de98, 0x58b333f1, 0x5f563ce8, 0xabd4888c, 0x7ec32afe, 0xc3c45d25, + 0xcac0e2be, 0x8c87e8b9, 0x0292490e, 0xc108ebfa, 0x0fc8467e, 0x7f32c094, + 0xe3a28350, 0x0921c1c7, 0x91b836f1, 0x90d37e60, 0x61f6fa23, 0xae218a8d, + 0x9f819016, 0x3fd29c46, 0x6d7c13af, 0xd7c05927, 0x25965e4f, 0x5b9a4ff0, + 0x1d396b88, 0x977679bf, 0xf9a78022, 0xd046ec02, 0x363cb2f2, 0x8ff7fad1, + 0x9e87f30a, 0xc6fed8d2, 0x816d7353, 0x6fbe9465, 0xb8c72dce, 0xf13f17c4, + 0xbfb44f74, 0x5287a315, 0xdc83684d, 0x75cfb0a9, 0x1295c4df, 0xd552031a, + 0xfe252cb9, 0x82bfc17d, 0x771f059f, 0x09ec9b9e, 0xb2671824, 0xe294fcca, + 0x8d247db9, 0x5bb4d7c2, 0x4da57422, 0x747b969a, 0xe9630ef1, 0x0173cb27, + 0x79ed6f1e, 0x2594ec0d, 0xfa0fd894, 0x3ca3b14c, 0x2ff72d34, 0x1fb5bc83, + 0x3bf46153, 0x27dfaebf, 0x48723e31, 0x2cefb271, 0x9e813355, 0xe42c732d, + 0xd6379639, 0xf00a5279, 0x55b8c97b, 0xcba7de14, 0x9f37684c, 0xbf085d52, + 0x7961317f, 0xa2ff7c71, 0x61b204eb, 0x5cfc8c4d, 0x95248a54, 0x0ea92bf6, + 0xe3c33fec, 0xd77e0092, 0x8769ffbf, 0x4be690fd, 0x1763a466, 0xdf10f71e, + 0xfad95575, 0xfeea8371, 0xd0f58152, 0x0b944cfc, 0x9ceec797, 0xf5f2ed4d, + 0x09ef14b5, 0xffe146fc, 0x98e87ba5, 0x9b749e14, 0xb892f909, 0xd5074edd, + 0x7e225e77, 0x8883947e, 0xa225845c, 0x51ea8e0c, 0x53852429, 0x681c3ea8, + 0x5a6585b1, 0xf3a7cfa6, 0x6231fd86, 0x2835fd61, 0x40fb2367, 0x7ca1aeb8, + 0x4d821839, 0xaef587f4, 0xafd0bfd8, 0x84af2f42, 0x67ed36b8, 0x604a63e5, + 0x9d67ed05, 0x357498d2, 0xcedcf32d, 0xba412062, 0x5003f4e2, 0x2e27cd57, + 0xf6b1210a, 0xf1169f5c, 0x0ed0a847, 0x78c64af8, 0xd38e9180, 0xf4f2f822, + 0xf3fce952, 0x09bcb60f, 0x892b8b6e, 0x6fdae78d, 0xca593b41, 0x4fb0eaed, + 0x17d0014d, 0xee237c24, 0x112d799b, 0x17d3a0fd, 0xc4686ec3, 0xef61ae7c, + 0x54a87833, 0x41fde1b9, 0x7d723c11, 0xa136fdc2, 0x8284863f, 0x2eaeb085, + 0xb5ee1508, 0x3e0bf1d1, 0xa71b7262, 0x15d20e3f, 0xaf6f8f5b, 0x307c8c37, + 0x90e54c20, 0x1d1fa5d3, 0x23a0f0bf, 0x52f68752, 0x7019ea95, 0xc99eb916, + 0x1b30389c, 0x7f38bdf7, 0xe42af119, 0x05e728d9, 0x9af6bbf7, 0x0c885c19, + 0x8a4438e3, 0x09ece1c2, 0x392de87a, 0x1157f415, 0xeb8503c5, 0x696f2e73, + 0x60e30217, 0x6e864ffe, 0x65df224a, 0x7e99b25d, 0xc62f631d, 0x20d99ec9, + 0xd85ed477, 0x7b150f01, 0x8f4c682e, 0x11de9185, 0x0172a7be, 0x10b909df, + 0x6fe46efc, 0xe82b0f21, 0x189ea657, 0x4760249f, 0xce082965, 0xeb61d52e, + 0xe157801c, 0x1a7f1337, 0x3a9663c6, 0x78eb38d8, 0x24d2ca5e, 0xd7fa7677, + 0x25ef5fe8, 0xc4c40913, 0x8b4abc39, 0x7bd17a06, 0x8c812349, 0x8d9f80ef, + 0xad59f871, 0xcfc78a76, 0xebf3c86c, 0xfe02bff4, 0x87fe1180, 0x5ff8519c, + 0x421456b7, 0xe70efe9d, 0xef9bd2c4, 0x15f90a13, 0xb6b43af2, 0x9cb52f72, + 0x2719f271, 0x0c80a197, 0x4f978a78, 0xccf41932, 0x23f33088, 0x817a728c, + 0xf6f9a3cf, 0xefc0de96, 0x0ea7b2f9, 0xf7def7e0, 0x2fe83745, 0xc63249df, + 0x6bf32053, 0x2bd81765, 0xb3a190d2, 0xda76f107, 0xf5c4e8cf, 0x9f9f057a, + 0xd4f94b54, 0x9e05fb0e, 0x0affd07d, 0x41ff5b07, 0xc7f41e40, 0x7bf3c545, + 0x852b0b90, 0xa7e2192d, 0x1879c27d, 0x45c832a7, 0x3560725b, 0xce9079f0, + 0x9f8cec17, 0xa5ab99da, 0x5879e1b6, 0x52f0634d, 0xa23f07e9, 0x06c260eb, + 0x8fb820ab, 0xe59f35da, 0x602d74af, 0x729fd6f9, 0x50c27e7d, 0x3eca545e, + 0x0aa97986, 0xbe0b9bf1, 0x2a00dc3d, 0xaa4e5fc4, 0x1f008fee, 0x9c6eb196, + 0xb883ae47, 0x72276a24, 0xa2e4a095, 0x722fa470, 0x9fc6bda2, 0xbfb49fb0, + 0x22cef1dc, 0xd52e77a0, 0xcaf71089, 0x91247f05, 0xc22aa85c, 0x3ef9adfd, + 0x5f07e710, 0x407f7ce1, 0x18cdf3a3, 0xbcb1a2df, 0xd4ce2a85, 0xdbf0092e, + 0x4e3b7294, 0xc4a2e9b6, 0x8634fcfc, 0x08bae367, 0x52f30608, 0x8d41fd78, + 0xb8e94928, 0xbec3f16e, 0xc164dfb2, 0xb8958b75, 0xbae7a082, 0xbe1e2c68, + 0x86ad724a, 0x16952ffa, 0x78f9e40b, 0xfefd6cad, 0x2e49c8e8, 0xbf62be85, + 0xd61f35a1, 0x3bcf949e, 0xa6fdf469, 0x57bdad91, 0xba5a0ce2, 0xcb737e31, + 0x27c12f30, 0xb56e8215, 0x496e8eaa, 0xa1888f10, 0xad148adb, 0x4dc5f80f, + 0xd60bb252, 0x240b4d29, 0xe164a706, 0xff9053f3, 0x1e127122, 0xf2d42857, + 0x6f423f10, 0x86acf9d3, 0xfb0dc052, 0xf92fd0fa, 0x89b0359d, 0x8f1bfabe, + 0x81c433a5, 0xed8e67b3, 0xaf67710c, 0x491ba5bd, 0xf3a60710, 0xcbf3001b, + 0x40d32b56, 0x79df65cf, 0x30f40edc, 0xd7f62dc2, 0x4bfb07f0, 0x586c656f, + 0x7125fe83, 0xe7cf7ab3, 0x05094eb0, 0x60e39978, 0x2a49cff0, 0xb7d58acb, + 0x132cfa4f, 0xef5a2515, 0xec4bc914, 0xffe7cba3, 0x89daefb5, 0xbd7be9a3, + 0x59372635, 0x9fe3f5a4, 0xd6e671d1, 0x3f105d58, 0x8cf65478, 0x773fb803, + 0x70975f3b, 0x01295d1d, 0x959f8b1c, 0xf079d3c8, 0x43fb611d, 0x1f943f1c, + 0xd98ecf3a, 0x2ef3a037, 0xd3c506d3, 0xb52559b5, 0x7212e710, 0x2ca7c999, + 0x4ba082f4, 0xea9bd026, 0xe5465205, 0x8dce2634, 0xdc6166af, 0xe8527f0a, + 0xbf02fff7, 0x31437ed1, 0x1ba09dca, 0x48f4c3e9, 0x4c75c812, 0xfeb9aabc, + 0x14fcabbd, 0x9fffbf8e, 0xb68429f3, 0x496943ff, 0xf53e3901, 0xdc535fc0, + 0x00f60f90, 0x977acf5b, 0xeebce2a4, 0x8ff77ee2, 0xb46a9e38, 0xd79872b2, + 0x637fbedd, 0x6fa2379c, 0x8efb67ef, 0x8ffaa80b, 0x4b6a2fdd, 0x1479c32f, + 0xfd7793a2, 0x8562ecbe, 0x7e30eb9d, 0xeb6349bf, 0x1bd505e6, 0xc0275cb4, + 0x806ff9e3, 0x5f5f14e7, 0xf161aa9c, 0xacdf011e, 0xf81a01ea, 0x9908ffdc, + 0x1fed9849, 0xb95f4ca9, 0xb7c5126d, 0x08d1e387, 0x179e01f7, 0x3257e739, + 0xe933c1fa, 0xb953f758, 0x601684f7, 0xff08c71c, 0x52bcba9c, 0xf3987fc8, + 0x29eb84b0, 0xaa01ff78, 0x3ff73d3f, 0x68e80e74, 0x9f319f9c, 0x171f18c4, + 0x43c8b37e, 0x983c4d9b, 0x27171297, 0xfb1cfd0a, 0x9e8bc637, 0x797af8d5, + 0xfb021930, 0xbef96725, 0x621b9c3a, 0xcb04ebfb, 0x14925072, 0x1e968b9f, + 0xb926052a, 0xc61b72a3, 0x33f8c5eb, 0xf833f8f8, 0xaae15438, 0xe633c7c0, + 0xf36217ab, 0xdc68b6dc, 0xc7421e6f, 0x89e3a393, 0x39731671, 0x7a0be314, + 0xe72abe0a, 0x7f515d74, 0xd3235bb2, 0x0c498703, 0x9ff88c7d, 0xca2b3bf7, + 0xa1cf0447, 0xfd039c5f, 0x51736738, 0xec271769, 0xc28e545f, 0xcfe269fc, + 0xe16af961, 0x1bb7581c, 0x36a4def1, 0xd8257376, 0xfee2689f, 0xb9717b5c, + 0x03c89a1d, 0x94f2c2a8, 0x67e07552, 0x191b87c0, 0xb9de2c1f, 0xb79075e5, + 0xb2bfadf2, 0x569dbc83, 0xbc60b2aa, 0xb41e9b45, 0x29c57ec3, 0xbd076fc5, + 0xe4c03a78, 0x8aefc8ce, 0x305bec59, 0xe0f6157e, 0x9f3fcbcc, 0xc5f9fc00, + 0x7a01d526, 0x1cd9bbde, 0x547c5336, 0xd0fc30d4, 0x7f5651fa, 0xade2f108, + 0xfe5dc3d5, 0x9cb2afe2, 0xe7969f6c, 0x9d7185f3, 0xd3f1b15f, 0x2f0f9052, + 0x1d7dc169, 0xfe3077e3, 0x97dc74a5, 0xc6a5a99b, 0x11be0bb7, 0x8d6f05eb, + 0x3c469be0, 0x7f7c665f, 0x172fd73e, 0xfe72bf05, 0x0120f811, 0x9de457a6, + 0xd28ff3eb, 0x7f8dd9fa, 0x62fd4bb2, 0xbfcb09f5, 0xf3de0d68, 0xdb672eec, + 0xe71360fe, 0x0177e8c3, 0xcb59cefc, 0xac4230f3, 0xed86a45c, 0xb4591710, + 0xecf5c541, 0xbfcf2da2, 0xbdd834f0, 0xabaecdf7, 0xb70bff69, 0x38777fec, + 0xa6dc2fad, 0xd3678e66, 0x763149b0, 0x5a7c0bda, 0xf943a510, 0xb39afdf6, + 0x40fe7b3f, 0x0b1e947a, 0x48d1edb7, 0x947c78ff, 0x8c68f704, 0x09740dff, + 0x7d852d1e, 0xbfe7796e, 0xe9fba035, 0xbc8112dd, 0x6e7c38cc, 0xd2fb8fd8, + 0x23a42780, 0x6e8453a7, 0x94bdf786, 0x39e7682e, 0xefed8c9d, 0x3fe40e69, + 0x5dce0fe8, 0x757e7e51, 0xfccfc517, 0x982ecc0f, 0xef57fcff, 0x4e3cc3b3, + 0xaf8c952a, 0x05983fd7, 0xeabe6476, 0xc96072cf, 0xe67fcf9e, 0xf36fc847, + 0x8b28fd0e, 0x99d2fd30, 0x9dfcd1c5, 0xd6737e61, 0x9bf386dd, 0x77c83c4b, + 0x65cbd7f3, 0xa8babf10, 0x12dbb190, 0xb94fc5c8, 0xce7c9c5c, 0x27f8fb8c, + 0xb8531ec1, 0xccc8effc, 0xa2f721cf, 0x9f11fd7d, 0x58fcb50b, 0x18e3c8bf, + 0x1e22cd13, 0x2c72b54c, 0xa87c6ebf, 0xe673e801, 0xc436772a, 0xf144bd01, + 0x57487c73, 0xa1f2bf68, 0x3f5cd931, 0x7f189539, 0xc39e04b7, 0x3baa0dfb, + 0x1df75f29, 0x1d1792b9, 0x9f1f297f, 0xfb0c9dc2, 0x12b327c6, 0x305f87c7, + 0xd611624b, 0xa303f3a0, 0x7de4cdf2, 0xbe4cc3e3, 0x2607bc85, 0x0bf6858e, + 0xc0fc9987, 0x53c7e077, 0xd8d9c2b8, 0x848a67be, 0xc3da80fa, 0x51bd7244, + 0x6fad72e5, 0xe1427c17, 0x897fc056, 0xfb610bf0, 0x7e7927bc, 0xe927dcfb, + 0xc1763177, 0xe3d9e30b, 0x3b7213fb, 0x6617f84f, 0x7593fcbd, 0x5bc6129d, + 0x22c47e8c, 0xd3c2f035, 0x3e54af20, 0xda2edf41, 0xbcc196a2, 0xfbdeab3f, + 0x9ca90fee, 0x7214167c, 0x469fd7aa, 0xdaff9d39, 0xa34fe47e, 0xdc167e9c, + 0x4e50959f, 0x73c7edb7, 0xfa72f1b7, 0x053fab3f, 0xf01bd6fe, 0x5b61f427, + 0xc3ea3478, 0x4fc410e1, 0xb7090fa0, 0x13fe46c3, 0xadf8277c, 0xddc595fc, + 0xf844ef41, 0x845df052, 0xc5df052f, 0xf0ead1e5, 0x083f3717, 0x589f01a2, + 0x75828ed6, 0xf6c5c586, 0xcb39ae13, 0x819693e2, 0x67d6fd6c, 0x43f582ad, + 0xb020c726, 0xec4613fb, 0xa427ecfc, 0xbef9fe6d, 0x963e9dcb, 0x65075fa3, + 0x895f042f, 0x1090e3a5, 0x16fbd383, 0x7d40f409, 0xf76396e0, 0x930b640b, + 0xbd1f9df7, 0x2c780856, 0xca97ee6a, 0xae1babf8, 0xb5fc445b, 0x054cefd5, + 0xea1ada7d, 0xad4f7989, 0x4494e507, 0xe25fa5e7, 0xfb857df4, 0x491bcd5b, + 0xadf94c95, 0xdfa0b499, 0xc168dfe0, 0xbe38b67c, 0xe67f3330, 0xe803e2bb, + 0x2978f80f, 0x5134b1a9, 0xf9f09a3c, 0x5ff3784e, 0x0baf1f68, 0xbf81306d, + 0x9346dd7e, 0x24be4fce, 0x1480baf8, 0x784f5f00, 0x20652933, 0x2ecaf3ee, + 0x0dee5738, 0x093cd39d, 0xf38c95f2, 0xdfc1fe87, 0xe0716fea, 0xc1a86fb8, + 0xdbdcf07b, 0xeb0216e7, 0x6aad3a85, 0x3b382261, 0xeb383125, 0x7cba338e, + 0x6a29785f, 0x618b85b6, 0x61237a7f, 0x3a38f671, 0xde0eb613, 0xaa7f704c, + 0x7ab32435, 0xa347db35, 0x2462fca0, 0xf699777c, 0xd79f231a, 0x057b6ed4, + 0x8455e7ce, 0xb6898724, 0x1a8d2857, 0x36b78bf0, 0x363d064d, 0xcbce29c0, + 0x894ffa3b, 0x16febfe1, 0x77b9e705, 0x00331bf8, 0x6acfe72f, 0xddd5f604, + 0x60ec5afb, 0x0a87ceef, 0x9adadf91, 0x191f76d7, 0xfee9eb05, 0x78a77f00, + 0x4eabf63a, 0x9447d5d6, 0x5c00ba78, 0x4b8dcc13, 0xfef0095d, 0xf7d9858a, + 0xdb3e4bef, 0xbf2c3b2b, 0x7afc8587, 0x7c41bf70, 0x378700ff, 0x13b37e46, + 0x6592efc9, 0xf7986cce, 0xd99efa92, 0x7f25cf80, 0xe2253b50, 0x963e2dab, + 0xee15b4df, 0xadf90017, 0x7d7bf2a1, 0x50d6fc8c, 0xff8bcdf9, 0xfbe5ae6e, + 0x202ddf95, 0xfbe009bf, 0x90af9f09, 0x51d0fcdf, 0x1afcdf94, 0x4acef9fd, + 0x2bf27b4b, 0xf2c29a75, 0x04d65c60, 0x00f01afa, 0x795bb2f9, 0x038c387e, + 0x37c2fc72, 0x24bce394, 0x4a7fef06, 0x20ec978e, 0x4f128798, 0x4bc7266f, + 0x4b1ca8ea, 0xc7267740, 0xcb09ea4b, 0x6fc83407, 0x65f9389f, 0xd98457df, + 0xbcdadef7, 0xc741dcdf, 0x2eab702b, 0x20bf7d0b, 0x6283cf2a, 0xb685f9e5, + 0xc760f9e4, 0x970779e4, 0x3da72a67, 0xeae8095c, 0x63f3e90a, 0xb27618de, + 0xe5f03b7a, 0x275c659f, 0x0f79e21d, 0x7276197f, 0x3fc5f020, 0xff8a1e00, + 0x9a6f9c3d, 0xbfec7e7c, 0xe853f874, 0xabec9547, 0x03ec35fa, 0x12a8de2e, + 0x351587d0, 0x328fd147, 0x5f85bfae, 0x0b875c65, 0x7e5ed23d, 0x776e61cc, + 0x088dca26, 0xc65b792f, 0xf38c3ffb, 0xc1c5ef17, 0x5deab079, 0xc042afb8, + 0x407c5ed9, 0xb83da3cc, 0x15debcc4, 0x148032f2, 0xe286dc42, 0xffc5e511, + 0xb5cf1947, 0xad5d1595, 0x23e51fbb, 0xaac2cf8e, 0x870812a2, 0x37e7e44f, + 0xf7bdaee7, 0x18af9c00, 0x0059c474, 0xe188f4ee, 0xa7ac0f66, 0x416a4a5e, + 0x49741679, 0xb974624d, 0xa379fbc4, 0xf031654b, 0x7256b79b, 0x86f1dd80, + 0xc1f785ff, 0x8bea7dec, 0x05a3e052, 0x8cc392f5, 0x834e787c, 0xb5295e75, + 0x854fc0bf, 0x7eb873a1, 0x245f505b, 0xea0bf7c3, 0xa3c0bc24, 0x9474fc3d, + 0x0edc296e, 0x6df8016f, 0xb30b6700, 0xd13e1c6b, 0x3afc55ee, 0xbe9e4bf8, + 0xc1972ab4, 0x571704ed, 0x02283bc0, 0xe7194cef, 0x057841d5, 0x3783dbde, + 0xc74f4935, 0x679e47b7, 0xb4a110fb, 0xbe6bad0e, 0x97887ee9, 0x4cfae034, + 0x90cc8bec, 0xac0b663d, 0xf3e97b6f, 0xc1690995, 0xa1efebbc, 0xf5d7ff7f, + 0x0037d91f, 0xece41dff, 0xcbae2a4f, 0xb338a497, 0x1df1dce1, 0xb75d2af0, + 0xfb336d34, 0xff313de1, 0xabb73e13, 0xc3710297, 0xf19e58b1, 0xf57ab995, + 0x4f6fb18a, 0xbe43b79d, 0x821f7357, 0x294d2179, 0xda274e2c, 0x0b3249dd, + 0x587e73fa, 0xf57c34a4, 0x1b49f821, 0x5c03061b, 0xbcf32e27, 0xb1e6cb92, + 0xd3ddd689, 0xe7109db9, 0x3802ef28, 0x2fb2249d, 0xe59f377a, 0x927e705d, + 0xad6667ae, 0xf8852b4b, 0xa0bcf1b2, 0x83403827, 0xde31a438, 0x11b88738, + 0xd0f9718f, 0xbf1611e4, 0xeedff034, 0x273b0724, 0x706a54aa, 0x3ac4f65e, + 0x8829f889, 0x8f88db0b, 0xf1e24c6f, 0x1fc20ec8, 0x46b1ce77, 0x11b978c2, + 0x971b79ee, 0x6042eaad, 0xf15e6cbe, 0xb579b3f0, 0x78d20f35, 0x8bb58923, + 0xbcec420b, 0x3223c576, 0xaf3c83b3, 0xe02bc044, 0x2a5dc233, 0xa7ff422f, + 0xfa8cad79, 0x607f2ef7, 0xba479c15, 0xfb84a56b, 0x54f9c62e, 0x009cced4, + 0xdf43c0fa, 0xf3693887, 0x69ed0447, 0x00296af3, 0xd73f8c78, 0x4bfb66e9, + 0x427bbc7c, 0x7e7351f2, 0x1ea2f4db, 0x3665d20e, 0x849acba5, 0xd5c8a3fa, + 0x168e462b, 0x7ab9c604, 0xe20bc6e9, 0xe6e17eba, 0xbfe7ba89, 0x74f1e249, + 0x4f6fbf1e, 0x6265489e, 0x47e422bd, 0xaf9093c8, 0x817ce0dd, 0x0702519e, + 0x4f00f372, 0x1a7ea18f, 0x4c5e7b27, 0x8f217962, 0x54afa74e, 0xe79e753c, + 0x0cbc7085, 0x2399f465, 0x6de7c78f, 0x078a31e9, 0xb6c0fedd, 0xe27c7d24, + 0xcc47cebb, 0x9881c843, 0x8c0e519f, 0x21e91bdf, 0xba46c0e2, 0x6721e918, + 0x7e40fa9b, 0x5d939121, 0xb9cb77e0, 0xe8d7caa6, 0x5a7772b8, 0xcbf703f6, + 0x65a4cf25, 0x7928c955, 0xa8572d16, 0x30ad2f4c, 0x1898b8b1, 0x970e5dff, + 0xcb923328, 0x3ec1270e, 0x830ddbe3, 0x0c2f2cad, 0x5c7145f7, 0x9215a78a, + 0xe83f809b, 0xfed04fdf, 0xbd926417, 0x712b7f80, 0xd6fdc50f, 0x9e3e7124, + 0x5fd2e1e5, 0x582e942e, 0x35a70fc7, 0x83473fff, 0x8ab2ecbf, 0x4f5625fa, + 0x153de135, 0xab25ffc4, 0xb93af367, 0xa2b9eacc, 0xfc29d69d, 0x7bfceeae, + 0xef566ff2, 0xcdffda2b, 0xb45ebfde, 0x21dac57f, 0x7fb69481, 0xa357f0f5, + 0xae7f30fd, 0xbbb548c7, 0x62bbf02f, 0xe529eb62, 0xdcf30d4d, 0x15fe3e44, + 0x96ab97ce, 0x8562bf15, 0xb762a23c, 0x67c4f213, 0xdf3b73f0, 0x90f414b6, + 0xf7bc26ad, 0x9ba04a01, 0xc0e2cc96, 0xc6a49e82, 0xcbce17dd, 0x2fbba091, + 0x246635e4, 0xc192927b, 0x61ab7abf, 0xcd47c814, 0x060c1f3b, 0x0ee80bff, + 0x05be14fd, 0xfa50da77, 0x436abced, 0x46705e6c, 0x193d9172, 0x6cdd1af2, + 0x3a724adf, 0x14051dc8, 0xadf6b80e, 0xf4d68427, 0x8035b2fb, 0xfb0f6a3a, + 0xc1659527, 0x986ba478, 0x9cb8fbc5, 0x2e9ecbe4, 0xb8b9bcf0, 0xe061d1f1, + 0x7ed89997, 0xef48693b, 0xe5a13f90, 0x74798fdf, 0x47b5b9e9, 0x3e3ee166, + 0xdc90cfdb, 0x6e838c6e, 0x24179c8d, 0x25603f98, 0x6fdc2ec9, 0x7f1c9177, + 0x307fcf16, 0x1cccbe31, 0xccffb31c, 0x1fbf45e7, 0x870fe70d, 0x375e5958, + 0x710ca79d, 0x89c401b8, 0x33e42165, 0xf55604f4, 0x09177d60, 0xed19f91e, + 0x7624f1ff, 0x336585ef, 0x4c87e5d1, 0xd876664f, 0x21f9656f, 0x12706ac9, + 0x73e4ede8, 0xbb7a01c4, 0xe0a6bd79, 0xf1c50ef9, 0x3c5fcc03, 0xef002260, + 0x01c06a8b, 0xd72d7479, 0x48e7ce2a, 0x4e66bfb4, 0xe3efd17f, 0xc85af39a, + 0xcad078cb, 0xb1162fea, 0xd396833c, 0x5af2005a, 0x952d73d3, 0x93b3f9b1, + 0xf13f9992, 0x78f14a62, 0x3eb043a0, 0x43f8c099, 0xa2065376, 0xbaa579f4, + 0x63f80920, 0xe288e02b, 0xb8ecdd21, 0x3f4bfa17, 0xc3cde14f, 0xafc46ee7, + 0x4a901ce2, 0x66fc3bf1, 0x47ee139b, 0x7829317a, 0xcb41c833, 0x839e1316, + 0x26b9aade, 0xab6b7d42, 0x257901d3, 0x9305e62f, 0x4c5b3e71, 0xc9ad9f38, + 0xa12dd72d, 0xa3e9af70, 0x14f8058c, 0xe92c512b, 0xcec54f20, 0x99f3e97b, + 0xacaf4cc9, 0x7a793134, 0xf589d93c, 0x7e3a25c7, 0x8457bc01, 0x4fce24f2, + 0x75b0b734, 0x0d29a76b, 0xf275f032, 0x25de7144, 0x3c7f832c, 0xbda08cb2, + 0x0353691c, 0xb9538c4e, 0xfd29336d, 0x07661147, 0x08b47d46, 0x0528c3f3, + 0xfda08f0e, 0x04a9b5ed, 0x1e7845e6, 0x4f9c8de8, 0xb28d206e, 0x70dfb685, + 0x74c2b889, 0xe92f1bbc, 0x2ddcbff3, 0x8d14d18e, 0xb62488a4, 0x78f863c7, + 0x00adc4c5, 0xf45894ff, 0x7b018def, 0xe318e14c, 0x49339c30, 0x1bb476e6, + 0x2e7b16e9, 0x8dede447, 0x853dfb91, 0xcd58c0fe, 0x66d87805, 0xfb07bf73, + 0x9506fe7f, 0x46175a24, 0x6a3ed7d6, 0x61537a39, 0x798c94b9, 0x6d1f947b, + 0xadd707c0, 0xfdc3f2ad, 0x62f5d787, 0x81df03fd, 0x7d66b95e, 0x87d80666, + 0x511f4e02, 0x7e033e0a, 0x7e32a472, 0x951f5c72, 0x79c9f5c7, 0xbe429fc8, + 0x9fa0cf80, 0x46606a5d, 0xe50738a2, 0x9fc0f5cf, 0xfd046cdb, 0xb6779fdb, + 0x12b9034c, 0xfce31ce3, 0x2d572c6f, 0x8547b25b, 0x76645f79, 0x4b977466, + 0x3c8c635a, 0xc1852bfe, 0x4d5675eb, 0x1bf1009e, 0x2dfb8a9b, 0x162e3c59, + 0x639d1fcb, 0x59f043f8, 0x51e58d93, 0xa9297e08, 0xbbae2bfb, 0xe2122e4a, + 0x3f1123c8, 0x28cbf04f, 0x61f3187f, 0xd7e61147, 0xe8a5f919, 0x7d015382, + 0xb4bf1ed4, 0x089027c5, 0xc8d27605, 0xb992072f, 0xbf26d29f, 0x5e03b65c, + 0x6497d696, 0xa4fc5d7f, 0x5b47f396, 0x4cacc3ed, 0x5f9f19ef, 0xa8f66148, + 0x41faab4e, 0x5b85e83e, 0x7b902e4c, 0x70b90dca, 0x325d513f, 0x95288efb, + 0x4dbea13d, 0x5b667a61, 0x667a8cc8, 0xc1e3cd9b, 0x161cd07d, 0xa78a241f, + 0x5c9af211, 0x35ce2c5d, 0x0cfcfc31, 0x1aa0bfe7, 0xe212761e, 0x74607f0b, + 0x014b7a1f, 0x9d25189c, 0x1fb93367, 0x00db4a78, 0x6c3dcbf7, 0x7c0d3a2d, + 0x04b20c95, 0x35c74f79, 0x38ad77dc, 0xdbfea1ae, 0x2950fbb9, 0x9e0afdd8, + 0xd76431e7, 0xd062d2a1, 0x37a65627, 0x29fd71cf, 0x4e60c3ea, 0xf70d0fa0, + 0x4c230d15, 0x53ddc54f, 0x1f937c04, 0x77bb8f6d, 0x0635d1a8, 0xef771ac8, + 0x98f711d0, 0x7bdc2714, 0x797bc1e3, 0xe1efeee2, 0x67bc60fc, 0xc7927fa6, + 0xf83f0562, 0x36dd8695, 0xb3276be0, 0xb2ad41c7, 0xa92bcb2f, 0x23fc09ec, + 0x147f0ce4, 0xf7bfc15f, 0x7cf62e79, 0xbe7c2dc3, 0xb614b88f, 0x61a8dd3f, + 0x082fe81e, 0xedc82efb, 0x1e6b6f52, 0x5f4b0bd3, 0x5d7c019d, 0xf98ddf38, + 0xc8a58fb6, 0x2497fcf8, 0x7409e96c, 0xaf182972, 0x92ceaa0a, 0x3df45293, + 0x81f594a2, 0x4eaed4b8, 0xfe3085c9, 0xb5cf56c3, 0x5a513f00, 0x4377c20e, + 0x82141786, 0x580db65e, 0x4a760199, 0x1ae14dc0, 0x8516c9bb, 0x6595c043, + 0xb0f87c65, 0xd6b5e675, 0xd03bec4e, 0x4f47b53b, 0x417be058, 0x39fd60ff, + 0x3e18f746, 0xf947ba00, 0xea1bba40, 0xdc050f02, 0xbff2dede, 0x25c60f87, + 0x87e103e2, 0x76ecbf51, 0x1ff78fc0, 0x73b37b97, 0x6fcf2c1d, 0x24778c88, + 0x9b25f246, 0xb05d8a72, 0xf9d1597f, 0x3e525887, 0xa067ff3a, 0xff766ee7, + 0x04e7f0b0, 0x45cbe4df, 0x234bafd8, 0x2e83de78, 0xe21fb0d8, 0x823cc349, + 0x63060eed, 0x744fdff3, 0x59282ea3, 0x72674d60, 0x1bb5efc9, 0xefd09610, + 0xc715401c, 0x75d7e81d, 0xe2e8bd45, 0x242725f8, 0x03c5ce09, 0x05c95f2b, + 0x019c33ff, 0x8f300fe3, 0xed3ec30f, 0xb951d66b, 0xeb029f30, 0x8fc09ec8, + 0xfa59f7af, 0xaf693027, 0x7dbf9977, 0x4fea33a3, 0x97b8fd09, 0xbfc62b77, + 0xcbf4cadf, 0xcfb66e8d, 0x163d7a0e, 0x801f610e, 0x1487008c, 0x62ba6a9e, + 0x6a1dbd45, 0x11be78a4, 0xd8f4a0e0, 0xf01a9123, 0xee4c8a17, 0xfbf012cc, + 0x8015853a, 0x5ffeb9b3, 0x340e20dd, 0x23fbf43e, 0x9178ef00, 0xe7d2eb1f, + 0x6cfd1ac7, 0xf588ffe1, 0x148ff086, 0x47e1088a, 0x7874fb41, 0xe0e9f14e, + 0x0c8de0f7, 0xfefe305b, 0x5af3ab78, 0x85779737, 0x98bc63ce, 0x572be5c7, + 0x4cba5246, 0x5a3f3120, 0x0a4a05bf, 0x2483f8ff, 0x82f18c9c, 0xe7f80516, + 0x8e449716, 0xadd9f0c5, 0xf875f543, 0xf68aca8d, 0x46fbded7, 0x2242323b, + 0xff1f9b5f, 0x3e83cb4d, 0x47f62fb6, 0x18f7db1f, 0x2bf643de, 0xed0db0e0, + 0x1c3bf6cc, 0xb5070f0c, 0x73ed76c4, 0x4dc3ef2e, 0xef10f98d, 0x4bebb3dd, + 0xee6fa3b4, 0xf05df2fa, 0x569d871b, 0x8767c408, 0x8a981e9f, 0x39a1d271, + 0xf442be78, 0xc6b4fdeb, 0xe473d84a, 0xdfff711f, 0x5b8f0a01, 0x582cf803, + 0xf1f671be, 0x0bbfa027, 0xdbc615c7, 0xcd52fc7c, 0xebe20bd3, 0xc81efca5, + 0xa7f31203, 0x7e01fb44, 0xd6bbdaef, 0x31105e48, 0x3497d2c7, 0xe820bfa0, + 0xb1a9cb78, 0x78fc95a7, 0x98efc0ba, 0x39afbfe0, 0x295edccf, 0x714e97f6, + 0xefbd91bc, 0x4ddb3ee3, 0xe02af735, 0x2394dfa7, 0xb8cc7713, 0xe2569ce3, + 0xfc6b898e, 0x63f06ac3, 0xc4f4bef6, 0xbf8b8804, 0x2f91e325, 0x9fdb686f, + 0x20dea1f2, 0x3377dc27, 0xd0a6f5e2, 0xfdf00abd, 0x97931b38, 0x7e1fc6f6, + 0xeb8fe51d, 0xf984de81, 0x9425837f, 0xdf5d231f, 0x8cdbf5dc, 0xf8f17ec6, + 0x02de8b6e, 0x6f0e82ef, 0x054e2d9c, 0x0747b47c, 0xa6ee9f23, 0x79d3f3f3, + 0xfcfce985, 0xd37b4fd4, 0x3efac0e7, 0x05d60e5f, 0x9feb7a7f, 0x4f3f00cf, + 0x0c98e5f0, 0xeac327c6, 0xb620c89e, 0xf88c9d28, 0x74636eea, 0xc0e9fc9b, + 0x7e3e5414, 0x6ce700d2, 0x536c38ca, 0x57ef1389, 0xbdfcfc24, 0x954dbed1, + 0xea0318ef, 0x8cdf68d2, 0x738a6d76, 0xd7c3de26, 0x6384bdde, 0x2052aadf, + 0x5954b3dd, 0x80fbb0aa, 0xe02e9f99, 0x6ff3d231, 0x09b6eca4, 0x19f0db52, + 0x67071de9, 0x3d353caf, 0x3fc2bc01, 0x4e10f717, 0x78f686f9, 0xd7cf4db8, + 0x7e8d4fe7, 0x5b6ad41b, 0x8ba46472, 0x83e85db1, 0x00a01852, 0x23f83f4b, + 0x48596ce3, 0x1a4bd2bf, 0xb579c371, 0x93e449ae, 0xc642bb18, 0xba7e4777, + 0xb59ec1cf, 0x97154fc5, 0x1193c44c, 0xf6b52be5, 0x55f02b31, 0x8565529d, + 0x6c1babfd, 0x52a45713, 0xb4fe8c3c, 0x5bee0a78, 0x84089a35, 0xce84c6c6, + 0x813885ed, 0x1c5d5f38, 0x7c0253da, 0xc0694fb8, 0x05f35375, 0xf8c61bea, + 0x15a1b599, 0x6ac3f056, 0x0b8c6533, 0xba23481c, 0x6dc7a073, 0x3daaefcc, + 0x9dc13ade, 0x0a73bda0, 0xdc4c9f6b, 0x6768f999, 0x51be3053, 0xf384daba, + 0xf6b92d1f, 0x321f8267, 0xd9afdd9d, 0x7f643f5c, 0xe9b78526, 0x1fd434ce, + 0xba1f6a63, 0x110941d7, 0x3e2177fc, 0xb929996f, 0x95efa39e, 0x2f585d3a, + 0xeb879d9d, 0x655f21b8, 0xed0f1e4c, 0xd75c54e3, 0x2917918c, 0x3cfa6f10, + 0xf5802a47, 0x71a92ee1, 0xe4fc1999, 0xe21c6c89, 0x7ac067f0, 0x19f19df3, + 0xcf20d603, 0x05d5fa88, 0x75ea186b, 0x3ba5b3eb, 0xbf81efce, 0x36f4b04f, + 0x8e51cf09, 0x7f12e471, 0xae94ff0c, 0xfea4f4a6, 0x7650a4d7, 0xe4f1f031, + 0xc40932b1, 0x656df1f0, 0x5d881256, 0xb1f3f20f, 0xde2af52d, 0xf8e42037, + 0x53bfce66, 0xdee865a7, 0x0ede6fa7, 0x886267f6, 0xfcb841c7, 0xd9cb80fc, + 0x3bfd7ccd, 0x1bab93dd, 0xbf308cb7, 0x65a4cfe6, 0x671d2a74, 0x960f4a76, + 0x70d2d51f, 0xe5f07318, 0xcf4083ae, 0x618fa0fd, 0x5a2f2b3d, 0x2390fc89, + 0xb77f00b9, 0xb7edf4b8, 0xe3d7d50e, 0xe8353fee, 0x74e0db81, 0x0faf1c94, + 0x56dfdc84, 0xc710ab2f, 0xe288adb9, 0xbd61fd17, 0x5eaede7f, 0x107cecb8, + 0x5bef86dc, 0xb2a4ec2f, 0xefca9436, 0xae1fa16e, 0x7e815722, 0x3f572318, + 0x4cd2fc01, 0x01399eed, 0x21fb08bf, 0x54a5f3d6, 0xc83f815e, 0xab8c4cd9, + 0xe544b98e, 0x9eba2336, 0xea0be88f, 0xf812b84f, 0x7ad81f39, 0x221df6ea, + 0xd4fe83fa, 0x9fdddfc1, 0xb550a318, 0x75700052, 0xd442fe25, 0x2c571857, + 0x10450385, 0x8739cbdf, 0x42af1b71, 0x5768a7d7, 0x8c7a679f, 0xd2ae0bfe, + 0xf46ffc15, 0x789c4433, 0x7ff08a52, 0x89117cf4, 0x31514e17, 0xa1f8238e, + 0xf208f014, 0x38c6453d, 0x21fc7b7e, 0xe29fffc6, 0xe3c2920b, 0xaf48bd7f, + 0xe083f08e, 0x4617c103, 0x4347f1fb, 0xfb2da75c, 0xf5f29691, 0x1f7f63f6, + 0x7b74f515, 0x6764887e, 0x7363d97a, 0xb5f37960, 0x0fc0d9b7, 0x83f5c499, + 0xf89143b0, 0x17c65ad4, 0x29671bfb, 0x05e46fb0, 0xc51790bd, 0x0adf88bb, + 0x4d58ac3e, 0x9e397e30, 0x7aa6a5eb, 0x8ef3cf16, 0x12900396, 0xec7a1252, + 0xf9675609, 0xb79e822e, 0x5228be70, 0xf7f028f6, 0x49756e5f, 0xb913882e, + 0x82703c79, 0x6078c25b, 0x7f823e9c, 0xc75bf6d0, 0xd758014a, 0xa093f519, + 0x7fde64f7, 0x7df09f1c, 0xdc9f2357, 0xbee5c290, 0x9ffee93b, 0x03c60bf4, + 0x4db53b5d, 0x7b7df157, 0xbe0d9d74, 0x5ed9c82d, 0xfe02bf96, 0xa6f5d035, + 0x3bf60a4b, 0xe7ef4535, 0xf05b385c, 0xf20b5c4b, 0xaf798df7, 0x37b4f9c6, + 0xc7e124fe, 0x8c5ebf73, 0xf2c2b37b, 0xa6768df9, 0xbfc2bb5d, 0x32abd233, + 0x26bfb125, 0xde1c6bf4, 0x8b6dfeb9, 0x5fe9ed6e, 0x53feefa1, 0x2bf457fa, + 0xcf1882ec, 0x5adb97a8, 0xbb3d09cf, 0xe309836a, 0xf5f03727, 0xae3c0df2, + 0xc3f70cfb, 0xdede3c02, 0xf782d17c, 0xb6550653, 0x63dfe53f, 0xd6d038c3, + 0xe97fccdd, 0xfbe2756d, 0xc6324a0f, 0x641c1e29, 0xd74c3d42, 0x3f308526, + 0x3e9098a5, 0x85dacfb0, 0x2b56b3ed, 0xe3d432e1, 0x7e40852e, 0xf1959e54, + 0xfa6f83c1, 0x0fff4067, 0x5a6deb1e, 0x70e37181, 0x4331f803, 0xa7dc140a, + 0x313b334a, 0x6f54dcce, 0xe6aabcc6, 0x03daffba, 0xf9aa277f, 0xf2c17122, + 0x39bd5f66, 0x7a044fb2, 0x96fc8c62, 0xcd11790c, 0x0ef3042d, 0x970b4e47, + 0x06e97ac0, 0xd602b0d2, 0x7635c3e1, 0xa788dd8e, 0xc6de7ca3, 0xbec8847d, + 0x1bcb3d41, 0x79e14929, 0x06fb7123, 0x6fb8250d, 0x15ae48a0, 0xd33ed124, + 0x60df667f, 0xf29ce038, 0x7a0c5ff3, 0x7fb1b488, 0xfb6355b0, 0x54872d4c, + 0x39327e02, 0x5e309995, 0x423eded3, 0xb764eedd, 0x82fb0ed3, 0xdbaf9fcc, + 0xccedc5dd, 0xfcfdfb6f, 0x986296c6, 0xd36ad6c6, 0x47632b4a, 0xe246bb8c, + 0x727c4671, 0xbfedc7bc, 0x61a35c84, 0x63c462dd, 0xe2194b71, 0x4fe29bf7, + 0x13d6c5c8, 0xebe06ec9, 0xb8ba27ad, 0x3c63dc61, 0x3b32e70e, 0xbf7604fe, + 0x326b78ee, 0x6e6ab3ee, 0x5a1bac27, 0x762e2cd2, 0xf3e3110f, 0x78dee760, + 0x3c07fc6f, 0xb935b7ae, 0x337d8fe5, 0xd851f763, 0xc51349be, 0x0faa3eeb, + 0x3cfd5f7f, 0xfe7e03e6, 0x13cc51f2, 0x4c86f85a, 0xadaf102c, 0x85e7e14e, + 0x03f81a03, 0xee3235e5, 0x18b9534f, 0x5625393c, 0x7960acdf, 0x3dd95b34, + 0x99afe59f, 0xf7e9e303, 0x927fafe5, 0x4df6f90f, 0xc00e5bcb, 0xbff01fdf, + 0x33bfb12c, 0x87cc6fe7, 0x95cb9afb, 0x2eb271c4, 0x9d7fe676, 0x034eb3ad, + 0xccda40ff, 0x79605efe, 0x8e6aaa70, 0xd9a5ef59, 0xd31ef155, 0xec492f0b, + 0x5f0a097e, 0xe2bf7dec, 0x7d9c06ef, 0xd5f06249, 0xbbf801aa, 0xb79be583, + 0xbe39c135, 0x5c6623f2, 0x9f3779bf, 0x4b33fbc3, 0xfcc16eb6, 0x4cad6f60, + 0x09d619f6, 0x9b53f3ba, 0x45e430e5, 0xbfb0d455, 0x98eb4023, 0x4c115527, + 0xbdb08e7c, 0xb70b3e73, 0x87eebfd6, 0x2feda83c, 0x9dbec1da, 0x0764d869, + 0xbf7ed3bc, 0xdc62fcf6, 0xc3e0a979, 0xea5e7b5f, 0x5a72610c, 0x379c3762, + 0x37c19cdb, 0x6383c223, 0x78a3faf3, 0x70b9fc64, 0xe067c5cb, 0xd7d9ef3c, + 0xe0067b3e, 0xf9d5f45d, 0x0d7f6067, 0xbd60f512, 0x6ff97dea, 0x7c521e78, + 0xdff72777, 0x117a5e9a, 0xbd3691cf, 0x6f41766f, 0xbb27f54d, 0xa6ca79c1, + 0x82caff6d, 0xfad2deb8, 0x2e77e831, 0xcffd41dd, 0xa2bafb04, 0x83e8326c, + 0x1ab1ceb6, 0x66b7b5e9, 0xf380376f, 0xf06f4a73, 0xdfe7237b, 0x2ecf2c82, + 0x3aadee72, 0xb8e179f1, 0x93356e73, 0x2061bd6f, 0xd40baa94, 0xdde7bb46, + 0x5e3a530e, 0x55fa01df, 0xeaf3cc3f, 0x73efd312, 0xd3a507f8, 0xf3faeccf, + 0xe66b17e6, 0xb434fb3c, 0x79b464d5, 0x01dc2dde, 0xc8f389bc, 0x55eeed63, + 0xd79b9076, 0x85f3c15e, 0x74f1b740, 0x2e5b4da2, 0xdc738376, 0xbb96d4a7, + 0xda836f30, 0x940b8843, 0xf287bfd7, 0x10e3b4d3, 0x3f0969c6, 0x2244dc17, + 0x538e763f, 0x98dcf3e2, 0x71c9cec2, 0x3a39c3fc, 0x39f4e3d0, 0xf8c72f3f, + 0x6ba39c58, 0xbd5cfceb, 0xefbf07bd, 0x77bb13ba, 0x1a87e378, 0x4a20dfbb, + 0x3468692f, 0x3a2dbd0f, 0x00383c09, 0xcf62430f, 0xa73e2683, 0xcc373918, + 0x03f405e9, 0xde722fff, 0x6247d693, 0x248f7a5d, 0x1b4d07d0, 0x26d239d8, + 0xf53df135, 0xad687ce2, 0x9e62ce81, 0x9087c96d, 0xffe0f6d3, 0xc979f8a6, + 0x8bf1d4ee, 0xcbd9d3c0, 0x87f8f589, 0xddbbe976, 0x8c96e36b, 0x607cdaf7, + 0xd3f704ef, 0x98f9e51e, 0xcc5acf2c, 0x96f82cf7, 0xbecf4f94, 0x17fde32c, + 0x517b82ab, 0x85f51b8f, 0xc23597d8, 0xb78739fb, 0x89d996a2, 0x04a5afb3, + 0xb39fb46c, 0x3f21d66f, 0xd51f5457, 0xc0ef8f20, 0x8b1aede6, 0x01f933d7, + 0xc71b113b, 0x9eeafb3a, 0x24dbd47c, 0x97f27e71, 0x437a1f5c, 0x56f1c789, + 0xb38dd39f, 0xfbc41fd0, 0xef1bdab1, 0x0a9ee28c, 0x50699dfd, 0x4cfa3f31, + 0x8d41c590, 0xedcc7fe3, 0x203ee466, 0xcf412f6a, 0x5768fb88, 0x3cf30468, + 0xe79626fd, 0x6a7efc69, 0x00d3c32a, 0xee04b387, 0x82d9750b, 0x52b8b9b8, + 0xd4cdc32e, 0x6c7b9115, 0xf6f7f85c, 0xe4977922, 0x2f309b91, 0x925de452, + 0x50bd5927, 0x613703d4, 0xfe10e51e, 0xdac03fbe, 0xeb4c2161, 0xecf97eb3, + 0x2c7efe4d, 0x3320b26f, 0x9cffcfea, 0x829630fa, 0xd5a67ee8, 0xa049fc4c, + 0x3ebdf82f, 0x22b27f22, 0x3575e449, 0x9ef7f3b2, 0xfa5f9d6c, 0x77a7bb47, + 0x5b73ec2a, 0x552776c2, 0xc6eb4b29, 0x4e2a1da0, 0xfabe2075, 0x03911f6e, + 0xc1ffc1fb, 0x76a707f1, 0xa57f1f8a, 0x6ab7faca, 0xe074dfb4, 0x4025be97, + 0x09ddbee7, 0x831773e6, 0xa3bf4a13, 0x9e7c14cb, 0xfec1c944, 0x073b995e, + 0xd22b1fe2, 0x2c63cc34, 0xdd00b0a6, 0x5e5c658c, 0x72a9aa68, 0xa5c72d1b, + 0xcdc875b2, 0x1ebe4ea9, 0x277f6169, 0xffc2d1cc, 0xe7db184e, 0x9682e597, + 0xe981d830, 0xecbfcc29, 0xdc31f2da, 0xb4eef1ff, 0x37582ebe, 0x7a4c0d4d, + 0x21b7e610, 0xf00933d5, 0xeeb4befb, 0x9b5f946a, 0x34fc0527, 0xfcb1ddc9, + 0x8871f8d0, 0xdbf4fc05, 0x61057187, 0xbc18f763, 0xe955943b, 0xa7c01e78, + 0xae323f18, 0x03d8bf21, 0x13883d71, 0xf11efbf1, 0xce3a7afe, 0xcc26e3f6, + 0xb64a6f8f, 0x59b47bf3, 0x00b608dc, 0x3fc7def0, 0xbef9972f, 0x5f775f96, + 0xa7bb2d5c, 0xb89eee3e, 0x08129e83, 0x8bef1839, 0x3b37de33, 0x4f300494, + 0xdc7f78d4, 0x307ebe08, 0x40f71bde, 0x5d0fb72a, 0xbddd1748, 0x5fd616db, + 0xf03d5beb, 0x09dc1b9c, 0x6b3c5325, 0x4d0c994e, 0x0d73ca8f, 0x3e708fd5, + 0x4e7e75f8, 0xc761ffb8, 0x2d7f003d, 0x79435fdc, 0x1dfc177b, 0x072a2d13, + 0xbb930ffd, 0xb9a75ec1, 0xacd4ff99, 0xd3cb7bb2, 0xbf4058e8, 0xc98fb834, + 0x89c4fa0e, 0x9bfe1b79, 0x3c7bee09, 0xa0499729, 0x92e9721f, 0x5c47ee1b, + 0x3dc7cfc9, 0xf6e9326a, 0xca9d7e61, 0xf96fe3f4, 0xefb1633d, 0xb7a04a4d, + 0xeb654d9f, 0x552cdb85, 0x9f198557, 0x9f740b3d, 0x70a8f26e, 0x599a9b4f, + 0x331c42a9, 0xce4fca35, 0x13e2092b, 0xeecedfef, 0xab5f7f4b, 0x81ebf39a, + 0xef66f3d1, 0xc7814600, 0x6fb8e92c, 0xbee38d3b, 0x4d4ce9d5, 0xd5a7818b, + 0x99dbe426, 0xeadb720a, 0x91e589e9, 0x1f719a1f, 0xcfa688e9, 0x02f71783, + 0xc480fb89, 0x7da2417d, 0x291586fe, 0xe91f1fe0, 0x74e77443, 0xd2ff5c42, + 0xf9039ef5, 0xf3a3047f, 0xa67f73fb, 0xff15dfc2, 0x82f48fab, 0xc5f187bf, + 0x4cdd73f4, 0x73cddf14, 0xd7f8b9ff, 0x79a3ddb4, 0xdcbc04de, 0x1578db9d, + 0x531dd7c8, 0x4dfa41ce, 0xf9bf7cdc, 0x9e3f653c, 0x61250ecb, 0xef3bc23c, + 0x4f180acb, 0xe6f687e8, 0x1d972f9b, 0x2a70bd06, 0x8bde09f0, 0xf626c646, + 0x8dfe8d5f, 0xe71773e0, 0x0db231f3, 0x493356ed, 0x5cac7966, 0x73ee636e, + 0xb37ee273, 0xe209fc9b, 0x98f62b3a, 0xd99fec08, 0xe1778941, 0x87754882, + 0x8af6165d, 0xf5942db8, 0xda1fcd21, 0xb95ea54f, 0x17c42569, 0xc8682fe0, + 0xfa80faf1, 0x56296e2b, 0x4f2bec0f, 0x79d607ac, 0x5a96c056, 0x58607a7b, + 0xdb7e84d8, 0x5f07d537, 0xe281f419, 0x82be2270, 0x605033e0, 0xc43e1fff, + 0x8000938b, 0x00008000, 0x00088b1f, 0x00000000, 0x59edff00, 0xe554707b, + 0xef773f15, 0xc3cdddde, 0x210366e4, 0x804d8404, 0x85701020, 0x5c7c0188, + 0x94422101, 0xd6da0300, 0x02101ba9, 0x16a52d79, 0x9b8cea9d, 0x8e233480, + 0xd29dad13, 0x542cce96, 0x2ec4952a, 0x4dd0689a, 0xd15c04ba, 0x63e02711, + 0xb46d63a0, 0xec083a2d, 0x98f8a71a, 0xe739ec76, 0x647dd7bb, 0xeffa7471, + 0xe5f98617, 0x7cebdfbb, 0xe3cefce7, 0x648a12fb, 0x40a50307, 0x676a733f, + 0xf1d31c02, 0xee016bb7, 0x0d1c442a, 0x00f250e0, 0x007f73e6, 0xd63c03c6, + 0xe9b6dc06, 0xdb007b5a, 0x2ed8c9ae, 0x95d6c801, 0xfc76edf6, 0x06dbb8fd, + 0xbab60173, 0xc00f77f0, 0xf9e9b1f0, 0xffbf8150, 0xbe956be7, 0x16bcea57, + 0x373f4d7c, 0xb772b025, 0xecf7000d, 0xb5ddc372, 0x9d701e34, 0x913ac4a2, + 0x46383668, 0x9dbac401, 0xef289d7b, 0xb1b0b870, 0xddc3db13, 0x5a64d759, + 0x1e17c2cf, 0x40074ec2, 0xf3e36e8d, 0x91bdb05c, 0x35eb8157, 0x87973cf5, + 0x33c685c7, 0xd752e6a7, 0x64df0e9b, 0x4e7dcf1d, 0x9aee5bd9, 0xc1ed1d84, + 0x508fa459, 0x87df2ca4, 0x43b4ccf2, 0xe47b3ec0, 0xf8ddfefa, 0xcb400e71, + 0xcce3376e, 0x987a9cf0, 0xe223df85, 0x8687b43c, 0x817ad35d, 0xb77b17db, + 0xff3d69bb, 0x7c4afa5f, 0x470700b9, 0xc4219dc3, 0x2e98be67, 0x4ec1dbe6, + 0x05e9e7e3, 0xd0402f2c, 0x39170ab6, 0x9c38e1a8, 0x1b0bf177, 0x9ff6b38f, + 0xaab37bd9, 0x222a89a3, 0xfa80031d, 0x3d3b0ac8, 0xa7accf64, 0x676e1400, + 0xfdc14105, 0x528297fa, 0x002bfa89, 0x5dfd82af, 0x01f7f1d9, 0xa73ef1db, + 0x67f61f67, 0xc6e01de9, 0x421cbbf5, 0x8c00d3ff, 0xdf1372e7, 0xc2b2fdad, + 0x65c806bf, 0xea411bbb, 0x0dc077b7, 0x9b7e89b9, 0xfdcb057e, 0xa7f05d43, + 0xcb623b2b, 0x53e23945, 0x5cb1f600, 0xf7813909, 0x169ce4b5, 0x7fb4280c, + 0xa303ecfc, 0x9f7d2e58, 0x7210e487, 0x67aa7842, 0x0dd7cd3f, 0xee96473e, + 0x74f8d2f1, 0x20b3fcb9, 0x9e09f908, 0x55018fe2, 0xd13b3df8, 0xfb855d76, + 0x42de0994, 0xe2fb7660, 0xc4da93eb, 0x7cc4aaf3, 0xfb6d7ebf, 0x1db9e40e, + 0xa9a2afed, 0x70af1073, 0x7c3d39d3, 0x31bca43e, 0x83d0b67a, 0xe394f517, + 0x8cdffd12, 0x52e6fe47, 0xf38c573b, 0x659cf53a, 0x400feca5, 0x8202d0fe, + 0x912af7df, 0x00a937b3, 0xcdaf1fe7, 0x9d73c0af, 0xeb6c0db7, 0xd49f71c4, + 0xd823ca85, 0xfdf3ceae, 0x5efdc75c, 0xaedd6f7c, 0x739fa899, 0x06b79a5d, + 0xe050c1e7, 0x8fa87189, 0xcf346786, 0x007e4923, 0xc445e3e3, 0xfc7df4df, + 0x189eda67, 0x58747e47, 0x1db0b8f1, 0x4813e2d3, 0x47f096ee, 0x7978830e, + 0x078703f8, 0xf81715e7, 0x543f9276, 0x222eb6f5, 0x8e83cebd, 0x0ce23aed, + 0xaf88f81b, 0x0f5c62a1, 0xbb7e1df7, 0x926b5f7c, 0x85753a1d, 0x7dc407e3, + 0x0a916b13, 0xfaffd361, 0xf631721f, 0x24c1f91c, 0x1347bf5a, 0xb5e6b33c, + 0xd238c0c2, 0x631c1b7b, 0x82c7beb4, 0xd9e26af6, 0x775d778c, 0x9fe3491b, + 0x69f9fd36, 0x41710fda, 0xc90f6f81, 0x43e478db, 0xf39d1e47, 0x8009a19f, + 0x4f764243, 0xf97b9ebe, 0xf34fe0f8, 0xee3dbf27, 0x8ffef1a0, 0x7415df91, + 0x079f0f1e, 0x1f23beed, 0xddf078ed, 0xd875e9de, 0xfc2a53df, 0x1dab47b1, + 0xdf5be347, 0x086b34b9, 0x123231f1, 0xd7d4bf8e, 0x86f49138, 0x4d985ffc, + 0xf908767e, 0x69f849ef, 0x8a29f905, 0xaffc415e, 0x8e34f6a4, 0xc18e5dc3, + 0x3d97ec65, 0x44bf2036, 0x203fb3fe, 0x40fdf5ff, 0x781fd1e3, 0xf3f654fe, + 0x419b41ae, 0xf1c600ed, 0xb85edc29, 0x835dda9a, 0x73f6758b, 0x3679f21b, + 0x80646bf9, 0x4c0109d7, 0x5029d321, 0xf648aa1b, 0xa3d63cdb, 0xdba7d4cd, + 0x55d0dff4, 0x9e2f7c9e, 0x53554723, 0xb54f23fc, 0xb502f225, 0x3fdc2bb7, + 0xed0df1e6, 0xc13fa24f, 0x740799a0, 0x2d383bc1, 0x5d4ff9e2, 0x7d6ffe22, + 0x4e8afe65, 0x13d6e73c, 0x13f7f72a, 0xce31ca4f, 0x78193c9b, 0xe536e748, + 0xe7da0f05, 0xfcc543d8, 0x1b6c5afd, 0x1ae74718, 0xba51165b, 0x38eeaaa9, + 0x36bf384a, 0xbc4348b4, 0xa3c1cefe, 0x19f3709a, 0x81eebfc4, 0x29d8675b, + 0x42719dee, 0xfdd88a16, 0x67fdfc55, 0xfadb0f50, 0xf219ff51, 0xf9871e06, + 0x0e3b5007, 0xc7f6478a, 0xdc8e2b14, 0xbc7c4d5f, 0xda26add8, 0x120b4828, + 0xf417da9b, 0x6c01ed6d, 0xc46057df, 0x71bf9789, 0x8d44e2fb, 0x8aafc9d8, + 0xde7b2dc8, 0xe28f30fe, 0x98c3b77f, 0x2ee9fc41, 0x0ca14d83, 0xd74f7d3c, + 0x4e954f98, 0xdfa992d8, 0xa0fc205d, 0x88bb003c, 0xaadd2d47, 0x5fbb441e, + 0xc70d56e8, 0x431f00d5, 0x8a02ed60, 0xb0630137, 0x01bff518, 0xc8031fac, + 0xa6894d1e, 0x68daf641, 0x6b1c3736, 0xd63ca1a8, 0x20e83ea4, 0xa4f8da3f, + 0x55d0e1f6, 0xffc6ee66, 0x27686153, 0x53ff11c5, 0xed82378a, 0xfb527b4d, + 0x7887c21b, 0xa953c35e, 0xb13a9bdf, 0xddb44aed, 0x3a8c5705, 0x997f033b, + 0x42b09304, 0x5c711e20, 0xdc70ecd0, 0xd97dbc89, 0x6f4953ed, 0x3f426d07, + 0x0fd94f18, 0x2cbf2b55, 0x7e287114, 0x2fec8201, 0xf3474207, 0x9df9ae50, + 0x63da5ea5, 0xcff45dbe, 0xfce52def, 0xbaa0f602, 0x65500d12, 0xde9096f8, + 0x176f2f51, 0x9937b9e3, 0xfc7411f1, 0xa6cded87, 0x1e91361e, 0x073635d0, + 0x079ee553, 0x4fb4edc1, 0x3f3c01fd, 0x903c6bce, 0xd7e96fda, 0xb4d3ae6f, + 0x2c7464fb, 0x75287362, 0xfd1e1f9c, 0xa17aa554, 0x73fbf537, 0x5cc09bc0, + 0x60133f4b, 0xeb07e902, 0x97b1802b, 0x8ee4678f, 0x344f97a4, 0x329c5751, + 0xd7fab1d7, 0x41697c9a, 0x344e28f1, 0xf120d505, 0xc8129365, 0xcfb79503, + 0xd7b943ad, 0xe0f0bc5b, 0x3dc7d43f, 0x9bd67ea6, 0xe173e0bc, 0x4a3de6fc, + 0xeff38230, 0xfe553479, 0x25baa10d, 0x79233ce3, 0xab53a9b3, 0x6e7e6073, + 0xb40e2d80, 0x98de48f9, 0x70e800fa, 0xe74afe50, 0xb94f8b4f, 0x6e46dc8c, + 0x5fffdcdd, 0xe22d46ee, 0xf8da7ca0, 0x201bc52b, 0xe27fbbf9, 0xe791b280, + 0x60dbecb0, 0xd73cc4f1, 0x56cf3df7, 0x61d3becb, 0xbab7db3a, 0x37d93bf0, + 0x6f463ebd, 0xc618ff63, 0x9150577c, 0xfcfa4fe0, 0xbd9d6625, 0x5e303774, + 0xcf2cfde8, 0x8362f383, 0x68c079c3, 0x47bca6ab, 0xf149c9ed, 0xcec0ada6, + 0xfe2ceefb, 0x500b63c7, 0x690f4b3f, 0xa0e0ac5e, 0x96ad4ae9, 0x95d373f2, + 0x4e4d14af, 0xe6ed27ca, 0x3687a5f8, 0x9c5165b4, 0x25e293f8, 0x7f858bf7, + 0x40ed4036, 0x829de2a7, 0xc383a3f3, 0x7b202e6f, 0xa5cce714, 0xb77dfcf5, + 0x76c2e8cc, 0xaf1cdf74, 0x17ac49ea, 0x2df38b75, 0x7ce352bd, 0xe724be79, + 0xbf68350f, 0xfb2f6306, 0x9e97f9f1, 0xc79f9077, 0xc62814ba, 0x47c5a28d, + 0xbea00d9f, 0xd270bfcf, 0xa2f84541, 0xa18e93ee, 0x2e03a96f, 0x50885504, + 0x3877b03c, 0xdb52bee8, 0x10c72ff3, 0x7d4f45d5, 0x34bd20e0, 0x471c2af4, + 0x41a8f61a, 0xb47afe0f, 0xf10745ef, 0x8153a5a8, 0xfdc9a531, 0xe663f71a, + 0xc23e7964, 0x092adffe, 0xf933ae7e, 0xe2d3f168, 0xce333aeb, 0xe54f6fac, + 0x763046e3, 0x0dfce096, 0x4f1c759d, 0x8e647437, 0xaabc5633, 0x28ead88f, + 0x4eefd7ee, 0x1bf9b71d, 0x941c061e, 0xd9e3d317, 0xd3878b51, 0x70f11a60, + 0xa26eb238, 0xe97f791d, 0xa844c364, 0x37afa918, 0xe56d7ccc, 0xf5e9cbcb, + 0x0e67ef62, 0xf1fe73ca, 0xfc17df1a, 0x48edffe3, 0xe209c9e6, 0x25b7e609, + 0x3ed94fe1, 0x8b23e135, 0xc0dbbf69, 0xbdfa44d7, 0x53a39c2d, 0x24335bfd, + 0xd85976fc, 0x242a0c19, 0xdbf38d9f, 0x41da106d, 0x3bf58ff6, 0x92f03fb9, + 0x981075c2, 0xd4deac71, 0xdfa9bd77, 0x8d5fbc7a, 0x30f54d9b, 0xfae283ea, + 0x6ea37b55, 0xbf316fec, 0x3476bd37, 0x0cbcf48f, 0x16599c44, 0xb2c67112, + 0xd2279597, 0xd0331cfd, 0x8ddec98f, 0x823c2761, 0x719b97e3, 0xc6277966, + 0xdfa46519, 0x30e6c6c7, 0x423d025f, 0xd8bcf4de, 0xfe3a9dd2, 0x2ba8814c, + 0xf67acd87, 0xd57b34cb, 0x02a721c4, 0x51e65bd7, 0x359e41bd, 0x8ffda768, + 0xe1fe42cf, 0x933dc7fa, 0x397b1ef8, 0xd669bd3b, 0x057b56e9, 0xc3ea8b12, + 0x5b91de90, 0xf737e490, 0x3921d860, 0x01a9e61a, 0xbdd27fd2, 0xd2ecc565, + 0xdd16f78c, 0x1d5fe38d, 0x6bd1febf, 0xc62def92, 0xe1e272de, 0x597f8a2f, + 0x43e29b33, 0x172788a7, 0x7cdd70ab, 0xeb81c3aa, 0x33a77f5a, 0x3f0bf748, + 0xadea88f2, 0xf213c4a5, 0x0b72b0cf, 0xfeeb04f1, 0x4afeb4f1, 0xe146192c, + 0x8af657f9, 0xe2e5647a, 0xaf77994f, 0x46e7164d, 0x74c98dbd, 0xffeab00f, + 0x9d442f96, 0xb16f7d69, 0xa03df10f, 0x6f30ac25, 0x9cbe07bb, 0xc6f28a50, + 0x509f3efa, 0x16eb5887, 0x54f5b479, 0x797d5036, 0xa0ceaff1, 0x74bce513, + 0x1f0fe5f8, 0x2ea5f6c0, 0xf2e63117, 0xc1d95c71, 0x0da2d37e, 0x721d7115, + 0xebbceb18, 0x7c73bd68, 0xc81ee88f, 0xbc40dbba, 0x5137ceb8, 0xb5bb16ff, + 0xa9d71b42, 0x9183b06d, 0x3ae499ea, 0xcac75eae, 0x8d864b14, 0x566bfe66, + 0x7bc42373, 0x57346e2b, 0x883dc625, 0x6b88dffc, 0x533b38dc, 0x5cec08fc, + 0x1b8c8ca0, 0x777b158d, 0xfd5321ba, 0x977ce113, 0xe3dcef5e, 0x24e6de46, + 0x1e2a1b78, 0xde84b67a, 0xa13b4e71, 0xffce94b5, 0xafb204d5, 0x9ceb7e75, + 0x9e7e4ce7, 0xc601fba7, 0x952ad69d, 0x279b65f5, 0x708baad0, 0x7626f31e, + 0xf5483732, 0x17fe8cfe, 0x8d0788cb, 0xb25c7007, 0x7d1da1ff, 0x90438854, + 0x421cdcf9, 0x3ce492a1, 0x74e2ffd8, 0x97d91be2, 0xa6fc9dde, 0xb2e5d37d, + 0xfdc45150, 0xfb88a6d5, 0x287d8f6b, 0xfe4dee8f, 0x306d6ac3, 0xfcd67ec9, + 0x80fe4d7b, 0xefd3dc5d, 0x7c4420a7, 0xd81e0b0a, 0xef2204fa, 0x1a778ad6, + 0x334aca0d, 0x7e442ff4, 0x035e4b7c, 0xea6d0b92, 0x33cce2d7, 0xcb1b49ff, + 0x5c393fe3, 0x03df9c94, 0x8a18eeb4, 0xc04dad7b, 0x28072471, 0x0b1c62ce, + 0xf97b63e4, 0x97ae2ce9, 0x6abb65a2, 0xa9956e38, 0x5b6b7140, 0xc9a9e6ff, + 0x05bfe1f9, 0xe91738aa, 0x95aa98a1, 0xa6fec527, 0x9560da1e, 0xbc17cf79, + 0x7888140d, 0x27a3f782, 0x47ee19dd, 0x6ddeb5df, 0x3d8273ed, 0xfa974ec9, + 0x0dfef9ea, 0x52a6f85f, 0xef9f019c, 0xfd6dc26a, 0xfbe953f5, 0x57cdfea5, + 0xd2a4bbf3, 0x02bf9296, 0xd5315f24, 0x7914ef45, 0xefb9bfb0, 0xd460229d, + 0x276a7e58, 0x6efdafe7, 0x8ec4e751, 0x84fbf164, 0x07826502, 0xdd653930, + 0xb857eea6, 0x55ea688e, 0x583e648d, 0x22dc7af3, 0x1e261e0f, 0x1486b620, + 0x487ced83, 0xf3ef5360, 0x16a34f2c, 0x76b63b62, 0x4bbfa26a, 0x3c97d620, + 0x00ee002f, 0x39feafc9, 0x52754c3c, 0x87964f73, 0x3eb14bde, 0xc4b1f914, + 0xfa8fdc19, 0x99c2f459, 0xcd5b8a22, 0xf50a682f, 0xbbea50c3, 0x679b736d, + 0xbde88fc5, 0xe81575e0, 0xda55e1dd, 0xc4b0ed02, 0x4d54d181, 0x1d66efca, + 0x5f9bb560, 0xc8d4abaa, 0xcb06dbef, 0xe6ce512b, 0x3b4abafe, 0x78b4f419, + 0xb634ba0f, 0x3009eb91, 0x95b65d84, 0x27f0a634, 0xf7290300, 0xb14e506e, + 0x8d61631e, 0x03a281df, 0xfde9ca67, 0x6fe4b9a8, 0x7347e4e5, 0x537bc50a, + 0x554bbd33, 0x7de27c90, 0x4d7f9aca, 0xafb3f0a1, 0x0b7b7f4d, 0x7bcda3bc, + 0x9e1b2ece, 0x4d1aadff, 0x05eb847f, 0x6edd9f51, 0xb7d5cdc6, 0xbc5f5c69, + 0xc78d1e05, 0xcca18a1b, 0xfac8bce5, 0xa78cddb9, 0xe352aa2b, 0xf03dcadb, + 0x91a11670, 0x635b4eb9, 0x0c0abfae, 0x7575775e, 0x6635b8ea, 0x36a6b69d, + 0x56e7fbf5, 0x930c9cdc, 0xc2ea6e39, 0x66c75b9e, 0xb90c7e71, 0x0cdef93c, + 0xb475e279, 0xf541c78f, 0x683c0b9a, 0x1c66e3a7, 0x01c92b6d, 0x177e28f7, + 0xa3fd9209, 0x53bfbed9, 0x719f8ade, 0x34553bf2, 0x1565ce2d, 0x29cd3f0a, + 0x514a7114, 0x9b276ca2, 0xa3ed9c72, 0xed9baf28, 0xe7ec5237, 0x533bc4d7, + 0xfc937914, 0xacc27c8e, 0x788aa223, 0x7b974b47, 0x8778a17c, 0x34dfa11a, + 0x5fd08ebd, 0x36a2de9a, 0x6ec5c751, 0x5ffef856, 0xc519f58e, 0x958bb5af, + 0x14f141a0, 0x2bfdc0f5, 0x54c3d615, 0x62704f88, 0x8f981dff, 0x4d8beea8, + 0xb6fd7513, 0xefe2f9b5, 0x9b780124, 0x64f168ec, 0x57e45d85, 0x286b0f8b, + 0xdf12cebf, 0x6ede9f29, 0x7755d3e6, 0x850af35e, 0xadaf4b45, 0x2f9ca7e4, + 0xb1463146, 0x475e20be, 0x53c7eafb, 0x917d23dc, 0xf32f479f, 0xadc2742e, + 0xa72e7eb1, 0x2fd36abf, 0xa839476e, 0x7adefdae, 0xeba5e734, 0x9530bab3, + 0x2b581887, 0xf2138fc8, 0xc7e6333b, 0x943ca6d5, 0x47e80363, 0xedfd4d6b, + 0x2eadf7cd, 0x0477efc4, 0x7e4c3d57, 0xb3d94675, 0xce2410ff, 0x9d187a4d, + 0x85addeb4, 0x090c3de2, 0x9b7ef192, 0x16f0179e, 0xd7b8e016, 0x54af718f, + 0x241777bc, 0x933eebe9, 0xb161d7d7, 0x079c764a, 0x25de9501, 0xdc3b03ae, + 0x443b6d45, 0x200b88ec, 0xfe81dfc2, 0x4fc45608, 0x9d73fcea, 0x9944723d, + 0xeff8e3c5, 0x9061f343, 0x7108ddc7, 0x3b740346, 0x32f042e1, 0xcb22b956, + 0x08af6ca9, 0x4baa5485, 0x82f64523, 0x5213a8b3, 0x2473a665, 0xb38763ce, + 0xd2a2fd56, 0x0b6011df, 0x3cfd3dd9, 0x0c79d61d, 0x0d4a4bc1, 0x555ca177, + 0x93695210, 0x1548601b, 0x39f32ff1, 0x4ddd6016, 0x01b8b77f, 0xfacd9fed, + 0xebf8f208, 0xa66a3ce9, 0xaf2d0cf3, 0xeb1615e0, 0x29129f24, 0xf39d7db2, + 0x2b11cfdd, 0x6f375e02, 0x03e2fc7d, 0xfbbf8995, 0x9eafc378, 0x2a3d3fa6, + 0xd3f70186, 0x665c4ddf, 0x9fb11add, 0x788f86ff, 0xe17dfd3f, 0x5215dfba, + 0x7ce8f23c, 0x8781f04e, 0xf60638f8, 0xb23f74e8, 0x7142b8d1, 0x128b8fdc, + 0x5c103bbc, 0x2f21b1e5, 0xf2e518ee, 0x43cca5aa, 0xab8d675e, 0xcf7a4ae3, + 0xe14e4d43, 0x91e4c1ba, 0x6aab7f25, 0x2af891fc, 0x8944a251, 0x944a2512, + 0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2, + 0x28944a25, 0x8944a251, 0x944a2512, 0x44a25128, 0x4a251289, 0xa2512894, + 0x25128944, 0x5128944a, 0x128944a2, 0x28944a25, 0x8944a251, 0x944a2512, + 0x44a25128, 0x4a251289, 0xa2512894, 0x25128944, 0x5128944a, 0x128944a2, + 0x28944a25, 0xffe12251, 0x72255300, 0x008000ab, 0x00000000, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0x00088b1f, + 0x00000000, 0xc5edff00, 0x30001131, 0xee300408, 0xd85aa12a, 0xaa66f6b1, + 0x964d2113, 0x5dbbcce4, 0x6db6db15, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x3d017e3f, 0x009b1baa, 0x00009b1b, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0x00001000, 0x00002080, 0x00003100, + 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380, 0x00009400, + 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680, 0x0000f700, + 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980, 0x00015a00, + 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80, 0x0001bd00, + 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x00000000, 0x00010001, + 0x000e0004, 0xcccccccd, 0xffffffff, 0xffffffff, 0xcccc0201, 0xcccccccc, + 0x00100000, 0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, + 0x40000000, 0x40000000, 0x00088b1f, 0x00000000, 0x1113ff00, 0x51f86066, + 0x423ec08f, 0xac9d0c0c, 0xc4b462a8, 0x1818990b, 0x12b102fe, 0x3c430333, + 0x203aded0, 0x2388107d, 0x16181858, 0x2fd610b0, 0x022bd404, 0x2c4062c4, + 0x19b7c401, 0x9cdfb348, 0x1f0f680b, 0xc8037f82, 0x3f4024be, 0x1c360fff, + 0xfb5f40ad, 0x1819d502, 0x8aa06bfe, 0xf2a26831, 0x9bf13519, 0xcf2684c1, + 0x2167c68c, 0x63247fa0, 0x0d75b600, 0x000400f1, 0x00000000, 0x00088b1f, + 0x00000000, 0x7dd5ff00, 0xd554780b, 0x673ef0b5, 0xf3399cce, 0x00fde4cc, + 0x108f0992, 0x2104e034, 0x0432b445, 0x3b69488c, 0xc514543c, 0xf791e109, + 0xb14a3e44, 0x44033bd2, 0x350af808, 0x0380a050, 0xed168d02, 0x06823ca0, + 0xfda2901c, 0x5a1bdedb, 0xcb6ab7bd, 0x880b851f, 0x52d11921, 0xf77ac5ea, + 0xcc9f7b5a, 0xd0049339, 0x9fdffed6, 0xcfb3767e, 0xd6bdaf7e, 0xf7b5ebda, + 0xa441c448, 0x84be421c, 0xfc8471bf, 0xa484205e, 0x83bf52c6, 0xa908a3a6, + 0x2d0867d9, 0xc26425cf, 0x5c64633e, 0x136fcd0a, 0x179a2642, 0xbcb19b0f, + 0xfbcb3373, 0xdd4f6d0d, 0x01c9cb4a, 0x1349d903, 0x49116f92, 0x1467211a, + 0xd146fec2, 0xf321117c, 0xb35b2ccd, 0x426cc8ed, 0x98b797eb, 0x3fb69988, + 0x81e0d7b3, 0x429dc2fc, 0xd439d088, 0x67255c1c, 0x8417fed1, 0x45d9b084, + 0x47e93bf3, 0xd7b15e5a, 0x5dfa8210, 0xaf34b68e, 0x01f3908d, 0x9864b885, + 0xed693bdf, 0x86548405, 0xd16494f6, 0x05bb957a, 0xa9c748b7, 0xc6442cdc, + 0x42ef828d, 0xa8bb40c8, 0x5712b66a, 0x97c39b3e, 0x75c5c704, 0xc742dc2c, + 0xa912fda5, 0x61daf651, 0xcbb2b5bc, 0xf9cf831e, 0x51c71380, 0xd3cf35f3, + 0xdabb6871, 0x2c370497, 0xbe2456b1, 0xf3bf1d30, 0x73e679a0, 0x32df5836, + 0x5daecf39, 0x587ee947, 0x9b686547, 0x7983625c, 0x17e7936d, 0x6aabfac4, + 0x6bcfd64e, 0x9f74a0c3, 0x3d3e3ca6, 0x95c4201f, 0x1257cb17, 0x60db09e2, + 0xea7921fe, 0x63f7d8f0, 0xb3f71124, 0x5c40d9aa, 0x427fac4a, 0x40ddf882, + 0x2b8011dc, 0xb5bbb569, 0xa9d176fb, 0x8985b7df, 0xf31f6dbc, 0xc3ef9a79, + 0x27a70e5a, 0x4d347e61, 0x499738f0, 0x1309fd74, 0x4ab85389, 0x3246b5fb, + 0x7acbdc33, 0x186405ef, 0x888f884d, 0xe25adf38, 0x2ed21fbb, 0x4e9caeb1, + 0x3245fe9e, 0xabbd74bc, 0xfbfed604, 0x57f585c4, 0xb03d900d, 0x2aef6baf, + 0xcb90ce7a, 0xf90292d7, 0xd0d6bbf9, 0x7926932e, 0x0257c008, 0x614015b8, + 0xcb40d07b, 0x4713bbed, 0xe16971ae, 0xc61f3c57, 0x75128c73, 0xcdbce3fb, + 0x4d27cba2, 0xaf838a4c, 0x46e679cd, 0x34f3a79e, 0xd211d189, 0x67c64220, + 0x8b6f882b, 0x9ba465b3, 0x79b3b7c5, 0x85b6ce2d, 0x38ff3482, 0xe685b834, + 0xce4ddf65, 0x4741e05e, 0xa4064916, 0xe98c913e, 0x7000de59, 0x9c5078a4, + 0x03ef2573, 0x68c5fa9a, 0x1f4d225e, 0x0107c616, 0x8e012b2e, 0x481ab534, + 0x6adbac1d, 0x86a70822, 0x05cf4521, 0x9d5a7035, 0x1b94e14b, 0xb1b577eb, + 0x09b8832e, 0x23bc1359, 0xf8526528, 0x1dcdd2e6, 0x23bdf30b, 0xdb4c1c12, + 0x00ce2ee7, 0xa5322a78, 0x32f8ed03, 0xc700bf1d, 0xae38046f, 0x3f18fbe7, + 0x463792be, 0x6079be37, 0xb37c6eb9, 0x38a7c74c, 0x5df829b9, 0x63853e3e, + 0x233f2116, 0x95f1c5df, 0xfc704b81, 0xeb949906, 0x8f74b7c6, 0x7771821f, + 0x437e31f5, 0xfafd58de, 0xd7ea5607, 0xbff5b32f, 0x8f9bbc10, 0xfff5c16f, + 0xd6cddc82, 0x6c47f03f, 0xafda26fd, 0x37477c76, 0xf700c3fc, 0x5fc07dfd, + 0x7e9b7a19, 0xf5aa83fd, 0xf1b137eb, 0xc83e0d5f, 0xf8e1b7c7, 0xd90791af, + 0xc52d07fa, 0x3aa64df1, 0x991693b7, 0x21752c72, 0xfd176bc0, 0x074d3a5f, + 0x45be71d3, 0x422482d3, 0x901ffb68, 0xc5870881, 0xa850df16, 0xf142c97f, + 0x0be316cd, 0x0052b424, 0x38e5afba, 0xa977773d, 0x326d24fc, 0x4bf185b7, + 0x10e9f942, 0x96cebf3a, 0x4fbd2f4f, 0x47773be7, 0x42e0dba1, 0x6ed0247a, + 0xdf8a5f1e, 0x8841e0c0, 0x1daa7b37, 0x7b3793f8, 0xf22c70da, 0x40599f00, + 0xf03d8e70, 0xf1a35e78, 0xbe86bb4c, 0xe7d06c16, 0xbcfa422b, 0x80f1ef3a, + 0x160d3424, 0x3a3afc93, 0x8fca19ee, 0x1f93e508, 0xe9047e52, 0x08792359, + 0x94d38dce, 0x4b59115f, 0x5f70cb57, 0xfe0c48ce, 0x91583667, 0x7dad2f1e, + 0x60832658, 0x640a563e, 0xf24178cd, 0xff9d3e76, 0x089d7c3d, 0x57e022e7, + 0xb4f73d6c, 0x47a14cd6, 0xb2779d2c, 0x31a75dae, 0xf5be0462, 0x963d0920, + 0x7b2ffb41, 0x87d18f62, 0x4fd3c7fc, 0xfd26ba44, 0xf7d74a44, 0xd87e34ce, + 0x733769ae, 0x3f635aef, 0xd3e7de9a, 0xae559f7f, 0x431a77cf, 0xe5ce1146, + 0xa36c810a, 0xa7583ffd, 0xf9c7572f, 0x7db1248c, 0x43dde3e6, 0x049992d7, + 0xfe91fa59, 0xeb64e7db, 0x497ae7a0, 0xca1f383f, 0x9a4ef704, 0x8dea107f, + 0x4b7c7d84, 0xe7b3ef86, 0x90d7ba25, 0x5225f39e, 0x9273f606, 0x25271b9f, + 0x08b753e3, 0x7edfe73d, 0x4711ead8, 0xfc475cf4, 0x4e221fbc, 0x968787dc, + 0x0697bfe8, 0xf0c7d7e3, 0x3e32dfc0, 0x7be6b4f9, 0xe4aef84d, 0xa97c1ad3, + 0xcbaa9e6a, 0xd3ee8457, 0xa1b05fd5, 0xaf3e5754, 0x5e5742b1, 0x2eb0f0d6, + 0x447c1a5f, 0x25a1ff57, 0x0fe574cb, 0x95d6add6, 0xab5f2acf, 0xdbe7dfcb, + 0xef7faba8, 0x72ba6dcc, 0x0e4570e1, 0xd97e37c8, 0xe1499397, 0x135de17e, + 0xf0c42ed9, 0x73f3c558, 0xcf4c0c81, 0x2e985c07, 0xf4a57a03, 0xa9641e2f, + 0x0e697b7f, 0xf78ab9d0, 0xd9758d67, 0xf8f12740, 0xf18f4f1d, 0x03780c78, + 0xe75f50e7, 0xbc40b579, 0x025df740, 0xefd48f3b, 0x97fce67f, 0x6f48e590, + 0xc7a332d5, 0x8b3397ea, 0xe5aa5e81, 0xad9d5e48, 0x58497eef, 0xb21075c0, + 0x08a9fb1d, 0xedd0aa51, 0x3cdd20eb, 0x70188e3b, 0x3e105afc, 0xdef3816e, + 0xf8c02a5b, 0xa7b23791, 0x78f9870f, 0x25be60e6, 0x4762f915, 0x69f25260, + 0xc5e7e009, 0x26605cf4, 0x3e0267a6, 0xca074f4c, 0x5030fd31, 0x607b6987, + 0x0327a609, 0x14ff4c41, 0xbdf4c068, 0x7fa62340, 0xf4c06c0c, 0x4c21033f, + 0x4c1e033b, 0x14d4f1bb, 0x90f903cd, 0x20226fbc, 0x2e1492e2, 0x3372a97f, + 0x5c85f961, 0x2e0bee6e, 0x27defbf1, 0xbc5048fc, 0x2c59beda, 0xa8e83f6c, + 0xf3a50893, 0xbbf6c335, 0x44bcb0e7, 0xdd843f90, 0xbbb2f95a, 0xf483d85f, + 0x9fc7ef6b, 0xf381dce1, 0x9e030def, 0x8af2247f, 0x0b5dba7b, 0xc047ba0f, + 0x86b75e6f, 0xd5fe5276, 0x7c31705f, 0x2e5c06b9, 0x039cf5be, 0x0cc2e8f8, + 0xe6fa79d1, 0x1357d7be, 0x34da75ce, 0xe8b7f1f3, 0x851b17f3, 0x741e4c49, + 0x0e18cc25, 0x9e74e0f8, 0x96fb0c1e, 0xcfdaa981, 0x79d90cc2, 0x85ea193a, + 0x77643d70, 0xd517e222, 0x3fdeb047, 0xf57d1e7b, 0x5ec79b13, 0x47b68a72, + 0xdf507b19, 0x0bc4fbf5, 0xe41933e9, 0xbc6ad268, 0x85aae704, 0x40e5f7fe, + 0xbcc257e8, 0x6c3fafda, 0x826e9a08, 0xe375bbef, 0x552e76d1, 0x7d7683d7, + 0xce449fe3, 0x5941f8a8, 0x6fae09d2, 0x9d9b3556, 0xa89d7e7a, 0x325bfbcb, + 0x0dfe3a9d, 0x4af4a0ff, 0x9c120a26, 0x2b1cd5bb, 0x835b24ba, 0x1bb7e740, + 0x8bee86f0, 0x6af5605f, 0x47d97694, 0x67dc2d3f, 0xe17df3c7, 0x05efae5a, + 0x9fb41b49, 0x70778633, 0xd34ace85, 0x449ce51f, 0x9e32f9a4, 0x39aef553, + 0x7cf0ab7b, 0x94126fff, 0xc8ff3ce1, 0xe70458d0, 0x9b786553, 0x76fba1ec, + 0x80938881, 0xbf205cef, 0x91acdc77, 0x3208afe3, 0x41acb7ae, 0x79516e7f, + 0xf2a79747, 0x9f3f2e8e, 0x3d034b4c, 0x91937e6a, 0xff285e8a, 0x043bcae8, + 0x80bbf627, 0xfe04add4, 0xcdef6a7e, 0x700adcf7, 0xc8a5b03c, 0x6873f347, + 0xbf4a3f71, 0x6427cd95, 0x3aaf93a0, 0x1fb4057e, 0x755c73d9, 0x51f43d5d, + 0x669a870e, 0x85ea13c1, 0xa6459b9f, 0x9f74a9d7, 0x72753a25, 0x7e5c5e5b, + 0xf6fe5c64, 0xc6d7fcb8, 0x908a149f, 0xdefdb169, 0x44f2f82d, 0x478043e0, + 0xf9bc3109, 0xf467fdda, 0x3fe47fe8, 0x44feffb5, 0xffb4ff87, 0xfda9ffdb, + 0xff31ee0f, 0x5ff5bdc9, 0x149e8a6b, 0xdd7b1ce0, 0xe198e78c, 0x7a0839b0, + 0x19ab7f82, 0xf637dcf5, 0xd01775fd, 0x26b3e75d, 0x8e7a6262, 0x93bff280, + 0xdf767bf5, 0x0ffeb75f, 0x8d0b3f2d, 0xb60b7f69, 0xef80fad2, 0x64c8adbb, + 0x184e5eba, 0x2f5d2841, 0xefd1fd78, 0x2e2f2a11, 0x91dee2b0, 0x0f4cbf05, + 0x51fb00ad, 0x799fcb2a, 0x08284071, 0xed979e76, 0x1808c311, 0xa3ed40f7, + 0xad2fee30, 0xa42d1e84, 0xd61375f3, 0xa305fceb, 0x2ee78a7f, 0x24415e9d, + 0xe77e3757, 0xb5241c02, 0xe052f85c, 0xf0e22840, 0xd55ef4a1, 0x8f31e092, + 0xfbeaf800, 0x2e8c60b9, 0x0eff2376, 0x5bc88966, 0x77205922, 0xcb53d7c7, + 0x5540e2fd, 0xb6ec581e, 0xfd53eac5, 0x37cb3e79, 0xa0fd3166, 0x052feb0d, + 0x958d49fa, 0xd597ecf7, 0xcec891ff, 0xac3f58db, 0x53d72d7d, 0x1572e9e3, + 0xe6aacba7, 0xa6f6862f, 0x7f32f55f, 0xa65fbefc, 0xafdd0582, 0x10e6cbe0, + 0x23b5616c, 0x6bef7a82, 0x6d511edc, 0x9e1ea089, 0x3905c7c5, 0x6944f20f, + 0x8ced097f, 0xf404cc07, 0xedd79add, 0x9adfd81e, 0xf33d7ffd, 0x63bdfa33, + 0xf80dd59f, 0x0ffaf350, 0x4c6bdf71, 0xdd02d991, 0x2a1ee8bf, 0x1dfad2ff, + 0x4d9d7e7b, 0xc61d3f68, 0x55d27648, 0x613565ec, 0xcafc9c53, 0xe03e7de6, + 0x98f2019e, 0x3b5447ca, 0x53fb7c5a, 0x45cff162, 0x4417970a, 0x7c88b34f, + 0xa9df6f4b, 0x5d39525c, 0xfdabde7b, 0xbecc4a54, 0xc43f7ea4, 0x1ba87be1, + 0x2e935fce, 0xf2e83d6d, 0x02ebcc10, 0xf3834b69, 0x13f9b6a8, 0x4aed4419, + 0x2e813590, 0xbee032df, 0xa12b9b10, 0x4d4df937, 0x4cc605cf, 0x75de5097, + 0xfedfea63, 0xc28b2381, 0x4f86fe7f, 0xe91ce1b2, 0x199e643a, 0x7f39fd42, + 0xbf1834ba, 0xa0f5dca3, 0x51eb8ac1, 0xe3a4abc7, 0xf5b10bd5, 0x755c6b5f, + 0xaefc753c, 0xcfac9f8d, 0x69f8e174, 0xb8fc7e30, 0x5c753b6a, 0xde7c572a, + 0xd886978d, 0x414b96fe, 0x72c3ce19, 0x947ee122, 0x14797a93, 0xcd8841d2, + 0x74ed4977, 0x97ca9f90, 0x4a5d3edc, 0xf900f366, 0x6901e60d, 0x5ef1c6d7, + 0xfb7fa380, 0x3a520554, 0x305f5c0f, 0x221a16d3, 0x3ca0f9b0, 0x7d414c1f, + 0x777be257, 0xe9fdf026, 0x17b87f4c, 0xb81d39fb, 0xf1c6f313, 0x1437c875, + 0x85a988d2, 0x1ffd3184, 0x8f9c46f1, 0x90238a8d, 0x98f81aa7, 0x0e11c359, + 0xb6245979, 0xe913f87e, 0xcdbf2b38, 0x572ddad7, 0x30e1c53d, 0x580679c5, + 0xbe47d066, 0x08ae5da4, 0xa3f364cc, 0xbe5128f8, 0x517f84e5, 0xc79d3a78, + 0x103826ff, 0x4a7ad9ef, 0x5d056848, 0x7c73248f, 0xbe184c99, 0x5e265c34, + 0xdd3c1d8d, 0x090ef8c0, 0xe83e411e, 0x5fc1fde0, 0x9451e694, 0x245655a7, + 0x7802df64, 0x089270e1, 0x91b7638c, 0xd8047588, 0x5af3a551, 0x1b79c1f9, + 0xa8ecebcd, 0x3a78f2fa, 0xb14bed53, 0x7e70db71, 0xe2cfdfb4, 0xae2cfdfa, + 0xd6aecfdf, 0xbf270aaf, 0x740bddb2, 0x87c058fc, 0xa78ea6fb, 0x7c28f1f0, + 0x113f51f2, 0x429dee2d, 0xd616ae0c, 0x22633d15, 0xc0337fb8, 0xf4e14ce8, + 0xe8e1c278, 0xb29050a3, 0xd7fe0081, 0xfd353b73, 0xed34daf3, 0x7a415388, + 0x99c7cd5e, 0xa1fc6061, 0x9ecff39e, 0xee78cdf5, 0xee6fa8f7, 0xf7a5beab, + 0xe6bef6fa, 0x3e75ed63, 0xd55f955f, 0xff5ffebe, 0xf869711e, 0x52829396, + 0x30ccaf2f, 0x126b7ed0, 0x1dbdfccf, 0x0f5144bf, 0xf7ebfa51, 0x4af802cb, + 0x5832c7f1, 0xa056ddff, 0xf05ee7df, 0xd74996c5, 0x63af9331, 0x14e97366, + 0x86264738, 0x526496a6, 0x5abfbf3c, 0x17709b70, 0xbce8ffe9, 0xbaf3e3ee, + 0x3a4051bf, 0x21917fb8, 0x6ec5eae4, 0x41fe0b35, 0x09d567cb, 0xd3d088a1, + 0x1b4b057e, 0x3e760696, 0x3b4f6e36, 0xeaf1045c, 0x6cde3e21, 0x0c1a4a42, + 0x845bed3d, 0xef2957e3, 0x35dede27, 0x2ed1b887, 0xffcf2f16, 0xe463e419, + 0x91b921c7, 0x46c1afee, 0x31e416f1, 0xfe8dc583, 0x3037fe90, 0xdc2159fd, + 0x2e5047ce, 0xa4040722, 0x573e8bfb, 0xec55d242, 0x33025b30, 0x62f0ced1, + 0xd9a60360, 0xce043c8b, 0x412f6961, 0xa05b7f79, 0xdf0fbf1c, 0xd1942edb, + 0x176ce4bc, 0x6774d3e6, 0x1f7e0960, 0x3fafaf58, 0x644baf7c, 0xd4225cf5, + 0xc3e0367b, 0xea05cf7a, 0x7cf5bed0, 0x3ff301a0, 0xcd31040f, 0x95f3626b, + 0x2fe82a96, 0x11a045fc, 0x18fed1eb, 0x41427aff, 0x2f7c3cfe, 0x79b797ab, + 0x2dd6084c, 0x777e7939, 0x197fe639, 0x377f6108, 0xb5fde0ec, 0xb30b9412, + 0xb3afdd17, 0xce96b863, 0x030fc9d1, 0xe5752beb, 0x3f063aea, 0x6f5750b1, + 0x5890def8, 0xfdf30056, 0xe4bbee91, 0xffe0890c, 0x5cbcdfcb, 0x3b0dcfd7, + 0x15eae8d6, 0xae89feec, 0x4ddec47c, 0x75bbbcba, 0xeeaf2ebb, 0xca65f54f, + 0x5679e9d8, 0x4205f975, 0x2fdb3f28, 0xf4375e79, 0x075cb722, 0x76bca05e, + 0x69f87c2d, 0x5c7083c0, 0x4840f545, 0xb3fcb833, 0x3493ec1a, 0x27d838ff, + 0xecc82fd1, 0x3b734f54, 0x3e40dad5, 0xe0267f7e, 0xc0bafcc6, 0x0c6fcc18, + 0xcffcc24c, 0xdfcc5e02, 0x09bf3123, 0xf00da9e0, 0xda3359f4, 0xe9671087, + 0x525b5d7f, 0x923f2043, 0x32f1c68c, 0xa2e637e4, 0x3f709a5d, 0xb3a70543, + 0x955687b3, 0x7122a6ac, 0x288beb55, 0x9939511f, 0x4e9adc80, 0xefd6bd79, + 0x037f2d77, 0xfef58395, 0x0721b987, 0x258aadf0, 0x0a29c993, 0xcfcda3ef, + 0xfae9da39, 0x432c762b, 0x3abcbb7d, 0x6d20bb28, 0xd3fd067e, 0x0dc4d5e5, + 0xb6e547c7, 0x4b9eff6d, 0x99f55dc7, 0x0f80da40, 0x0107214b, 0x91b376bf, + 0xde58ae72, 0x009cfcdc, 0xd93b34f3, 0xee9d98be, 0x0a79e208, 0xc5710f71, + 0x519cdaf0, 0x7f6e7e87, 0xe825f47a, 0x3c87dcdf, 0x2ee92bfb, 0xe50d1a41, + 0x8a30c46d, 0xf7d80cd1, 0x78582f1f, 0xe791ec04, 0x80b7201f, 0x6bf1e73f, + 0xe74ecbcc, 0x4eeded05, 0x93bb0b06, 0xf36393fb, 0x1d96ff42, 0x9b1b95e6, + 0xe5e89d97, 0x52bccd62, 0x772854a4, 0x4ece780a, 0xf04f1824, 0x79fa6df4, + 0xb2f30d3d, 0x44af3df5, 0xebc02f3a, 0xc4af0e44, 0xfd42f09e, 0x5e0e3134, + 0x6bc37d89, 0x912bcc28, 0xf4230578, 0xebc18333, 0x79fa2999, 0x780d733d, + 0x4179d2a5, 0xaf0e54fb, 0xc2f09ed4, 0xbc1c6a7c, 0xd786fb52, 0xd2979858, + 0x0df1d45f, 0x8e8b60cb, 0xefc0d82f, 0xfb5729a7, 0xd2ca8c73, 0xfddf4f7d, + 0x005150b0, 0xdd40d3f2, 0x3789a4f7, 0x5329f2e8, 0x4ffaea46, 0x9756319b, + 0x58a078cf, 0x3b9acf97, 0x7fbed759, 0x795d34f5, 0x191103fa, 0xcb9a8bf4, + 0xd6f9e3db, 0x7c2f523d, 0x0728cbab, 0x35d7cec1, 0x4163c99c, 0xbd63ca81, + 0x3e8baff0, 0x5b17db86, 0xff436f87, 0x39789fea, 0x1fb40bc7, 0xe0f03d83, + 0x55f7f450, 0x13ddfa73, 0xf3be4668, 0x7c8c204a, 0x6fb71f68, 0x8738801d, + 0x0381823c, 0xd378df68, 0x82788215, 0x19e6dfea, 0xfceb3ce0, 0xfc13329d, + 0x8be69dae, 0xefc8230e, 0x3771d452, 0xa94107cd, 0x8905b881, 0x1f6dea4c, + 0xb7f38dff, 0x9ecf07e5, 0x1d2f7e84, 0xb44cbb34, 0x56af09df, 0xf9a7643c, + 0xdd98f7da, 0xfbfe2fa4, 0x63f7c92b, 0x97e62706, 0x93f97da9, 0x5f8e8411, + 0x00d13bb8, 0x180aa7fc, 0x07f82a44, 0x1f41b3db, 0x05ec791a, 0xfd47fc1d, + 0xfedd65f6, 0x230b1e14, 0x43f752df, 0x7ee84f3d, 0x8538c034, 0x56e3e07d, + 0xe225db89, 0x067f74f9, 0xa7c0b3af, 0xbfe59569, 0x9697eca3, 0xda6cdfcf, + 0xbf9ceb0e, 0xe071d961, 0x1cb767cb, 0x0bbefe38, 0xdbe3a1a7, 0xb9435f54, + 0xe7f36bf0, 0x53dcf07f, 0xbd7e22f1, 0x119b9755, 0x70f9dd2e, 0xbdcef6ef, + 0x7b53d312, 0x57b7d3c2, 0x18587f42, 0x2eaa8ee3, 0x7bdf84bf, 0xd42eb1ca, + 0xd539172f, 0xfdc9b5f9, 0x601d0f80, 0x8545d97e, 0x2fc812e1, 0xbdd1317a, + 0xf95faa02, 0x46834bf2, 0xda345ece, 0x2af0be93, 0xddea91f6, 0xc5ea1226, + 0x4625d23e, 0x48d2996b, 0x578a50e5, 0x2768965d, 0xf5477fe4, 0x986349fa, + 0x12e20abd, 0x62daa59a, 0xbf36ac69, 0xfaca58b0, 0x4d42faea, 0xdfc7c7eb, + 0x817d3127, 0x427f07ea, 0xf5e814f8, 0xe84f5506, 0xae703d6b, 0x0cec3ea3, + 0xbbaf5af7, 0x728d75dc, 0xd2e51ae5, 0x45ffca35, 0xcf29f7e3, 0x55ea66bf, + 0xe058bf9e, 0xd03e074a, 0x76098f45, 0xe064468e, 0x2d0d555f, 0x1adf3f0c, + 0x8ff9009d, 0x7d5abeb9, 0x72f8c439, 0x5cd79588, 0x788108a6, 0xd426e2ca, + 0x49163f7e, 0xe17c6f79, 0x1fd32356, 0x20ff5a6b, 0x73cf80bb, 0x7ce1a93a, + 0x4532e6a4, 0x695f4a28, 0x1bd61346, 0xfe233466, 0xef491915, 0xad8d9f72, + 0x8027e54f, 0xce4fc093, 0x3cc5cc6e, 0xf5f227e5, 0x8e1a93f0, 0x9f955f67, + 0x02f30adc, 0xf3da54bc, 0xf7905e30, 0xdaeebf13, 0xa9c20746, 0xfe80ce9b, + 0xed7e066f, 0x02a63429, 0xf71809dd, 0x4262dd58, 0xa356e439, 0x5eebed8b, + 0xbeac4fe6, 0x03f18bbc, 0x17d38d89, 0x538fc7be, 0xe3a2d8d5, 0x16f83d4b, + 0xff8c578f, 0xf1919f7e, 0xe2848bef, 0xfc4f4147, 0xafa2f150, 0x5b2e6b7e, + 0xdee8f374, 0x767deeef, 0xc6c73ee0, 0x953c7053, 0xa470aa1f, 0x38dbb9f0, + 0x627c27ba, 0x38412970, 0x48fb7276, 0xc98d5f3c, 0xc55edc0f, 0x81e3d9f9, + 0xb5adde3f, 0x38fb5af7, 0x387156c7, 0xd1040eac, 0xf51d242e, 0x5aaec138, + 0x6f07766f, 0x49f0c437, 0xa164d8e6, 0x9d035e62, 0x849525a7, 0x16a6d196, + 0xe7f02b98, 0x2af8825c, 0xfe1d24d9, 0xaf3429c8, 0x288db7e3, 0x13069b27, + 0xe957f001, 0x615f2faf, 0x6b3af164, 0x4b3bb7f2, 0x927fbce9, 0xb820fbff, + 0x6d601dd2, 0xebfda033, 0x63bfaea2, 0xca64dcd2, 0xfcf8132f, 0x72d1b79c, + 0xc1e6f8cd, 0xade4014e, 0x76fa89a4, 0x0cb070f1, 0x8abfeba6, 0x1c524cdd, + 0x20a197e8, 0xc2317662, 0x612230e5, 0x272ae8dc, 0xadcb47e3, 0x95d7a40e, + 0x63ee2239, 0xadb7b713, 0xc81b3b07, 0xfc848a52, 0xeac894cb, 0xb44109cb, + 0x4ec199a3, 0x8a7d806b, 0xda4ede60, 0xeb009f31, 0xb8f2041e, 0x4c9fd70b, + 0x6f412b22, 0xbedf1aef, 0x164fbe18, 0xfe02cf7d, 0x3b6cca5c, 0xd53d8029, + 0xf40a1beb, 0x2c10c1be, 0xcffad174, 0x5085a21a, 0xfd169b2f, 0x39a58931, + 0xd3e4d710, 0xff987ff8, 0xf437963b, 0x912ce7cc, 0x5721fce2, 0x5fcb6a86, + 0x012f3d10, 0x129ca79d, 0xba909e50, 0x09bd4de3, 0x2bf70f10, 0xb1878f23, + 0x2fe93d31, 0x8f4cb9ad, 0xeac721ed, 0xf70537f9, 0x79ba63f4, 0x63f2e3b9, + 0xd8d31fa6, 0x2797fdc3, 0x0ec1f8ea, 0x1d8d03a0, 0x11e4b07d, 0xa4355fc1, + 0xcabf7e91, 0x6dd6bf7e, 0x601a0cbf, 0xf8f1f77e, 0xb3d5220b, 0x22f78f3c, + 0xff744bb0, 0x6cd455df, 0x593bcb3d, 0xf9873fce, 0xc0f9baf3, 0xec045361, + 0xce1eef7b, 0xdcfb062c, 0x51e8c66b, 0x3ff5c82b, 0xfdcdf260, 0x5a331cef, + 0xedefba69, 0x4b9076ed, 0x9cfa724f, 0xd846a24d, 0x0f8f1f47, 0xaafaed53, + 0x55ca8c5d, 0x0f9be046, 0x7f774244, 0x3c1ee697, 0x1c2efa16, 0x8adfb397, + 0x9ad80afe, 0xb12cec2f, 0x16bb4d12, 0x679671f7, 0x45eb34ed, 0x57ad8e7c, + 0xd668f5c1, 0x5b15fb8b, 0x50f082af, 0xfc19fbd7, 0x787ce69f, 0x14fbe8db, + 0xdd7e33f0, 0x5b344ad5, 0xfbf8881a, 0x5a9bc057, 0x8d272f83, 0x00c2e3ae, + 0x5854d0df, 0xf2325b4f, 0x6ff8bebf, 0xf466fc77, 0xcdb71606, 0xf386a7f1, + 0x86fb15fb, 0xe11d8026, 0x220daffc, 0x21e7ddc8, 0xbf7e921e, 0x81343cd8, + 0x73bec55c, 0x2e75db8e, 0xe8095d3a, 0x911d094f, 0xbec00b4b, 0x539e4471, + 0x9a9eb3d0, 0x91ed0f2f, 0xb20ed14b, 0xa2388647, 0x1af71e1a, 0x993f7fdf, + 0x6379c1d1, 0x20e804b8, 0x04e0a2fa, 0xeed55eff, 0x5ed1c73d, 0x247123b2, + 0x710d2f8b, 0x08db473f, 0x908a9fd8, 0x146f1f41, 0x91057266, 0xb0cc46da, + 0x8f52e16b, 0x63fd34ed, 0xed57dcfc, 0x31496cbf, 0xbb720539, 0xfa0f1cec, + 0xc32b7043, 0x1e89b2cf, 0x33f69d83, 0x7f4041b6, 0xdba72de5, 0xaca98e31, + 0xbf409129, 0x472c8f65, 0x9b6d533f, 0xf81da5ab, 0x0f704864, 0x794fe021, + 0x14c7f0b8, 0xb28eeb1e, 0xc3fc807d, 0xb8f32fe8, 0x6fbb1a6c, 0xd0aeb187, + 0xa0f0f409, 0x5cf203cd, 0xbbcf0ce9, 0x205957e0, 0xfe008e45, 0x7d2ceba8, + 0x0e0635c0, 0xd9b0d285, 0x2442a983, 0xa56be50b, 0x4d205112, 0x86648997, + 0xffcfeb7c, 0x6c289cc2, 0xa216e9bd, 0xfebfefb0, 0x8de1e01b, 0x8edeb2cd, + 0x6fe7d619, 0x0be7d16a, 0xcdfcfa23, 0x4ff3e96f, 0xf74941c0, 0x0c2fb5f7, + 0x37f088c4, 0x47fe0085, 0x8588990f, 0x97eaabae, 0x2703d466, 0x9cf0d954, + 0x7305f8f8, 0xde47f208, 0xec08b57b, 0xb4bf954b, 0x6f01b8b3, 0xaf2825f8, + 0x811fa97a, 0x0dff7273, 0x8cb7b544, 0xff64b900, 0x3ed80ddf, 0x9fed3cfa, + 0xe0f8ffd6, 0x947a5fcf, 0xf9f8ffb6, 0x1210497e, 0xdf87d594, 0xef59aabb, + 0x41ba1e1f, 0x2161ff3f, 0x664abe7d, 0x2f0bfafa, 0x187e2ac8, 0xdba5df18, + 0x17f5c695, 0x907f9697, 0x6e20fd45, 0x8182e400, 0x4455efb1, 0xbf46afd3, + 0xe1e9c89f, 0x019dc05c, 0xc88a63e7, 0x85cfeae2, 0x7a0348de, 0x1bc768fa, + 0xe74f4069, 0x4fd04b03, 0x6767bd55, 0xd5e79c12, 0xf0e1bfcf, 0xaedf7a40, + 0xdc82c6a7, 0x0c21bcf4, 0xd3dfa0f3, 0xf8477be0, 0xf4598e57, 0xc91db9fb, + 0xd17def88, 0x30a8457b, 0x7c0e7b43, 0x8ee87c55, 0x383272a3, 0x9de3181c, + 0x0fba5dfe, 0x780d9b55, 0x7c2aa65f, 0x038677f7, 0xa2366c1d, 0x8f7aabdd, + 0xbe3ea091, 0x7bb456ed, 0x813eed55, 0x8dfec771, 0x5e5718a5, 0x61af1124, + 0x664cba24, 0x75ae7a40, 0xb7ec039f, 0x926e7f55, 0xefc81725, 0x78a3fdfa, + 0x548c7180, 0x069a28f2, 0xb2cf494e, 0xa9bff022, 0x57ae7bdf, 0x5f7e3edf, + 0x78d5915e, 0xddaf9225, 0xc97af8df, 0x37688253, 0x5cb25ea9, 0x7d500f17, + 0xfe0651ba, 0x4a0e3f1a, 0xfa739a90, 0x017f0835, 0xeb917f3a, 0x51ce5439, + 0xc3cfa2e8, 0x3cb106bf, 0x80952b9c, 0x1bfeb047, 0x851744c8, 0x3234d547, + 0x032cd209, 0xe42c7bc1, 0xefefe615, 0x7a0473a0, 0x237dd8e8, 0x84bab7da, + 0xc33f5df6, 0xb7c8edfe, 0x07119c3a, 0xb6544dc4, 0xe2ee319a, 0xf2320be3, + 0x37e1658d, 0xdc6f101c, 0x145992f1, 0xf1f5b0a9, 0x8362e49e, 0x37e7f003, + 0x4e19aecc, 0x571d962e, 0x7b9a2fd1, 0x00f8b78f, 0xafcf49fe, 0x273d94ff, + 0x7d678064, 0xe98b9e32, 0xbd8575c9, 0xedaafdc5, 0x42bae452, 0xb3d3c817, + 0x5aefdc6d, 0x72f80b9f, 0x06e197d1, 0x6054a979, 0xf4480efd, 0xed7e849e, + 0x924bd6cc, 0x076c32de, 0x70653a7c, 0xf852762f, 0x945e25cd, 0xf28ee60b, + 0xa48740c9, 0x96fdc59e, 0x51222449, 0xf80cb039, 0xa3cc08ea, 0x59b65efc, + 0xb9a2f8c0, 0xe775184f, 0x69e1c400, 0x1a4e57d7, 0x124adfb1, 0xb37cb4c6, + 0xf802bcbe, 0xa5578534, 0x95e0fcc2, 0xf0718c3b, 0x5a3ea089, 0x930bfbbd, + 0xfd751c76, 0xfaea217f, 0xd1e5973c, 0xfd45fd4c, 0xf70129be, 0xd8c8ffd9, + 0xe65f380c, 0xf8e0f699, 0x985cfc55, 0x7e58ea4f, 0xa00c8922, 0xeba3cfe3, + 0x9e607382, 0x918e8242, 0x92309f2c, 0xdf93c7ad, 0x0eb03d73, 0x36f277ed, + 0x56aaafdb, 0xd61c3221, 0xf20de743, 0x5b47ac37, 0xb3af9aaf, 0xaefd377a, + 0x7690ffb5, 0xf7bb5fac, 0x5fae930b, 0xe7a0cf6e, 0x7dd33110, 0x37cdd758, + 0x71b4c343, 0xe1bdaa23, 0xbac78724, 0x0267e7bb, 0x720d3dbd, 0xd8071658, + 0x8127aa18, 0x032c676f, 0xb7c742ac, 0xc79ddcdc, 0x2ce5a2f2, 0x76b4c83f, + 0x54fe86c2, 0x32fa310f, 0x3329ae41, 0x68438f78, 0x37c54ece, 0x29c744d4, + 0x12d93d93, 0x1e4f75f2, 0xb09659da, 0x6474fff5, 0x5ebab0dd, 0xbf7518e4, + 0x08e10bd6, 0x641d43c6, 0xbd7c41f2, 0x4fc62671, 0x1fb68e12, 0xdd173e07, + 0x5a11e547, 0xc1f0a36f, 0x6de3b071, 0x5645cbbc, 0xdd067cd0, 0x1b77e01f, + 0x502f5205, 0x4bda8cb8, 0xa3d01be5, 0xd4378ef7, 0x4cdd70d8, 0x6dd6b06e, + 0xfa47fb03, 0x0123f943, 0xb930ef5f, 0xdd741e70, 0xe5a34d0f, 0xb983cb19, + 0x384bff60, 0x0ede6a1a, 0x8b70efe7, 0xa74bc61b, 0x6127b1b0, 0x7fe700da, + 0x023c2906, 0xc5319574, 0x88ec1235, 0xffac1ceb, 0xd0f0d154, 0x46539054, + 0x28d27cb2, 0xfb8ed9e2, 0x49c716b3, 0x30499137, 0xf20ef83f, 0xb3d6ed17, + 0xc4349107, 0x5d4275f6, 0x3e9f8c21, 0x7064a588, 0x8bcbca06, 0x9eaa7cb8, + 0xf7f59f6f, 0xea3f0024, 0x3f01f7e2, 0x201279b3, 0x1b1c8c8e, 0x9fed6a26, + 0x0345fd6a, 0xdf50e93c, 0xc124597f, 0x287fe464, 0x5e67fa5f, 0xff857b42, + 0x1a824cb2, 0x9cbfec3e, 0xd777cfa4, 0xb1f6c34b, 0x4a12167a, 0x839eadee, + 0x11fd7484, 0x7f2d7f7d, 0xec24f5e5, 0x77698c8f, 0xe9d91c80, 0xdb3e476a, + 0x46831215, 0x1174f7aa, 0x9dc1f182, 0x6d5df64e, 0x265339df, 0xa2679411, + 0x40474fd8, 0xb2630881, 0xf413f5a9, 0x1eb7561f, 0x35ef8129, 0x7ce30da4, + 0x1256c26b, 0xdbffc5ec, 0x970b0011, 0x3f29fce6, 0xfdd4ed8a, 0x9037b588, + 0xb38fd690, 0x52222da2, 0xeab75a5a, 0xc00a2bd7, 0xd3947704, 0x2b37f04d, + 0x72d1b73c, 0x23a3a883, 0xba6ea8eb, 0x275f3242, 0x061d181a, 0xe262bb7f, + 0xaf3c9a6d, 0xf83edddf, 0x291309bb, 0x602a8ddd, 0xf55d9fed, 0x972c6fef, + 0xae807c62, 0xd76bdb3f, 0xbcb895e4, 0x6b87e68d, 0xf2b8cef2, 0x8cf2b894, + 0x567f7cb8, 0xc91ec3bf, 0x1ca9b836, 0x13f7eab7, 0x3a4fca24, 0xa9b32332, + 0x309e4f04, 0x226133bc, 0x6a8f8dc4, 0x5a79c0f3, 0x59b82adb, 0x5f830fb8, + 0xb9e19bad, 0x832eddcd, 0xaa3adf7f, 0x7688b8ed, 0x7209c12a, 0x27bc2da6, + 0xe7687982, 0x330bb4d2, 0xfc3aa4fd, 0xb3ebb601, 0xe9117cff, 0x87fe4d7c, + 0x765aef58, 0x8faf9274, 0x6e2bef83, 0x3be0b770, 0x92bd026a, 0x77bf9144, + 0x992ff9ec, 0x7c633fdd, 0xf3d333ab, 0x43adf206, 0xb7cb5382, 0xa41f30fc, + 0x0e5c65e7, 0x935c7062, 0xb886517f, 0xb787f78d, 0xa9c703be, 0xcb27d175, + 0x73fb1e40, 0x20d1d9cd, 0x1f2d809f, 0x217af4f8, 0xd6f18664, 0x7861a18b, + 0xc866adff, 0x7a05d111, 0xf016fb7c, 0x75574417, 0xda4ffc22, 0x284007db, + 0x9755c5fb, 0x7db53e59, 0x5dc7ec0b, 0x009b7f0d, 0x0e4f1ef7, 0xd2201f68, + 0x8355a5fc, 0x487e6227, 0xf7c816fb, 0x3f2c1c53, 0x81807dbc, 0x0921cfb6, + 0x76ff6113, 0x8abf193a, 0x3967bfe7, 0xf7e755ff, 0x29cf7f4e, 0x66a90b80, + 0x1c0b7dfc, 0xed9f94cf, 0x73b538ec, 0x9d9fdd17, 0x9fc8cc4b, 0x10bc6429, + 0xe1ce938f, 0xf20ee78c, 0x8df50953, 0x926b384c, 0xcf68fb62, 0x7f21736e, + 0x0f6ea1be, 0xb3e9d79c, 0xff3f900b, 0xac99ec87, 0xfdd2c6a4, 0xfad29a36, + 0xe3271593, 0xed1106a7, 0xda8fe99e, 0xda78fe51, 0x0561d6cc, 0x1b534afe, + 0x7c2b8fdf, 0x4c4c571d, 0xdf24b91f, 0xdacdfd81, 0x950cf946, 0x240966db, + 0x309c80a8, 0x81394655, 0x3341a3aa, 0xdc5537cd, 0xddd27180, 0x335ad2fa, + 0xd0a9bfce, 0x26760993, 0x9a693f55, 0xd44cc9ea, 0xdb4d65c8, 0x67cab958, + 0x5e69729b, 0x12102e73, 0xad9779c6, 0xbb424dcf, 0xf3eec4bc, 0x743b5fac, + 0x573c1afb, 0x9b3ae1a7, 0x68664312, 0x2fffc2a7, 0xf0c93dfd, 0xbef57efd, + 0x7507df28, 0xd30ac9dc, 0xec0cca87, 0xf1527e3c, 0x44cb3ae1, 0x39a208cf, + 0x4d03279f, 0xa448e068, 0xfdf0d1f6, 0x8c7843ff, 0xa3fdf586, 0xf1daf8f0, + 0x84fc71c5, 0xa0bb8df2, 0x67259aff, 0xf30cdc79, 0x5df0a9bf, 0xe98c442f, + 0x77b06f8c, 0xd077e804, 0x3e4c0abb, 0xe753b42f, 0x1ad1fb3d, 0xf5d4d794, + 0x60787f58, 0x9d99dc12, 0xc5fe795d, 0xecfdb49d, 0xf775591f, 0xa4be5581, + 0xae46bde2, 0x11eec618, 0x4fbb29ab, 0xe80a7208, 0x3aeaed77, 0xc4264f24, + 0x18afaf8b, 0x609e8228, 0x828ff805, 0xb7432efb, 0x9c18132f, 0x9caa9e60, + 0x08bb8843, 0x2953b3d6, 0xf97d86ae, 0xa05e2952, 0xf071b2a4, 0xa75e097c, + 0x03d78dfd, 0x7aeae779, 0xfc72610d, 0xefa604a6, 0xd0f10249, 0x8dffcdf9, + 0x811adb71, 0x13e21f03, 0xb0bb30b6, 0xc357972a, 0x79f74ee9, 0xe7e3973e, + 0xc17e3973, 0x1deea306, 0x3e908a82, 0xbcd89a4f, 0x523eb9aa, 0x9fb0da45, + 0xbd7d66aa, 0xd82faa6a, 0x83bf701d, 0x8690f1ca, 0xf9eae5f5, 0xc2f96fe1, + 0xa0f77fa4, 0xa361f711, 0x09f1c999, 0x8fb93d23, 0xb5fc7f01, 0xffcde511, + 0xc2a2fbe6, 0xf1624061, 0x8b5f00c3, 0x9ff84441, 0xec394916, 0x95c0676f, + 0x93307831, 0x02f5a76f, 0x9aaf35bf, 0x361f01cb, 0xffcea22b, 0x64628f78, + 0xcce5c37e, 0x4fbd1e9e, 0xc8133b46, 0xffbd5ac1, 0xe7d54539, 0x10ff72d7, + 0x129a33d3, 0xa9bedc99, 0xe9077049, 0x2b4d277c, 0x5ff800af, 0xc021699c, + 0x3d72e76a, 0x746a42f3, 0xfaadc031, 0x76bb4bbe, 0x7c37d011, 0x74be022f, + 0xc7ecd18a, 0x967fd172, 0x0fb3fe00, 0x7cef8c43, 0xfdc0eb48, 0x9dab6098, + 0x4f1355c5, 0xefda3ce6, 0x6ee9d5a9, 0xe3533b88, 0x641d4e49, 0x46f5cbfe, + 0xf3dc096f, 0xfa63ee0d, 0x574687c3, 0xeb23dc36, 0xd011caf2, 0xd744cbbb, + 0x7b2025d6, 0xaaf6b61d, 0x5a9ff85f, 0xfeae7180, 0x23dfa5ca, 0xfdd3d157, + 0xbd3d7a2d, 0x61b34493, 0x07ca9b5d, 0xfc742386, 0x6e61d6ce, 0x40cad666, + 0x93ad4be3, 0xd54d3dd5, 0x7187bc3a, 0xbdf088c8, 0xff91fede, 0xf0fc7ed1, + 0x684bf06f, 0xef681fed, 0x7a43dbd0, 0xfabed9e6, 0x7e674d5f, 0xeff2b892, + 0xb093becb, 0xf93fb50f, 0x0825c9eb, 0x37d228d7, 0x3e7a6469, 0xa144779d, + 0xb46f4fed, 0xdda77f23, 0xf9fdbde1, 0xbe053654, 0xd194b393, 0xf486f55b, + 0x4837606d, 0x57eac89c, 0x768a186f, 0xfedcb184, 0xea40df3b, 0x133ba015, + 0xa1390069, 0x696ae4cc, 0x9c63c4d7, 0x5bd267b9, 0xbcb45f40, 0x0dabca1e, + 0x82fcdeec, 0x8da2b6b6, 0xecc22f30, 0x02cde5c3, 0x78c53881, 0xdad115fb, + 0x3560a889, 0x80cdbc36, 0x55d83f4a, 0x55df63f2, 0xbf79ee3a, 0x3d26efe5, + 0xbf2a82dc, 0x7abd31f1, 0x9ff83a70, 0x901c7a54, 0x48cc95e8, 0xe074ae07, + 0x3e0c67a7, 0xe02c97b4, 0xb82b1bf7, 0x478eaf9e, 0x3be30df9, 0x281fb70a, + 0x2d70aecc, 0x47daa3fe, 0x0f403b54, 0xf294b3be, 0xf37d119d, 0x0aea421d, + 0x80f84ed1, 0xd2740dcd, 0xfe70ff83, 0xba53eea6, 0xd8d0f8cc, 0xd10321a5, + 0x6497b9c8, 0xcd3697cf, 0xa3ffe2b9, 0x826eb8a2, 0xb40c97bc, 0xbe365c81, + 0xf70a91d2, 0xcebf98dc, 0xdb3c46da, 0x662df7e8, 0xfed02f2a, 0x90b871ee, + 0x0cc8647f, 0x97928c0f, 0xa2f2d214, 0xfb9436e2, 0x09c4a9a3, 0xc6decefc, + 0xa762dffa, 0x3b4246ed, 0xdbba77c6, 0xa2dea42b, 0x2afc5f69, 0xe9725fbb, + 0xdfed1da0, 0x734b1297, 0xbe748f80, 0xa77e476a, 0xba53bbfa, 0x8958d5df, + 0x1e1db9eb, 0xd5854a45, 0x3d03f715, 0xfb93088b, 0xd86277b1, 0xf46358b9, + 0xe9ff00e5, 0x9644d778, 0xe08b7ed3, 0xbc54a231, 0xef0257b7, 0x2ebed536, + 0xca486400, 0x8216772b, 0x5864d91d, 0xf7428f74, 0x34b0c4a7, 0x576d08fa, + 0x04e6c033, 0x9cc4c293, 0x7de7fd3f, 0x5ed1ff34, 0xaba7de23, 0x266139d8, + 0xa2fad1d8, 0xa2fbf8ff, 0x7975bf74, 0xbcbabfba, 0xbf9f45bf, 0x814f6cd7, + 0x36942cfb, 0xd8cf70dd, 0xb73baa64, 0xf4d7ce8d, 0x354dc99a, 0xd9b37211, + 0xe81980f7, 0x071e8c5d, 0x3a729978, 0xe17c8046, 0xc044fd6f, 0x559250f7, + 0x072f80ff, 0x9992e7e8, 0xf3efb3c1, 0x9eec289b, 0x6967551d, 0xc36d94da, + 0x597a68fd, 0x6f8c0908, 0x045d194f, 0xf7e130e7, 0x97183c4f, 0x265367e5, + 0x4cfefc4d, 0x68437ed3, 0xded79c19, 0x5c27bc72, 0x856bcf4b, 0xb87177e6, + 0x8b47d557, 0x53445ee0, 0x3061a4d2, 0xc90be92f, 0x0abbfb0b, 0x17c8d13a, + 0x3fe2cdcb, 0x115a3f76, 0x2d89efe2, 0x7b873a07, 0xf8e9e39b, 0x0cf8bee3, + 0xe8532ee3, 0xc9cfc030, 0xee376656, 0xfda21652, 0x43ae6fda, 0x44b8d5bf, + 0x60b5d709, 0xa0242d80, 0x9f20991d, 0x3932260c, 0xcb41611a, 0xffb986cf, + 0x0b4e0e3a, 0x9ab930b6, 0xbbe033ec, 0xc1400b31, 0xd5fbb902, 0x700f18a9, + 0xc9a7f376, 0x5b6e01e3, 0xbb0270ef, 0xccbdf5a2, 0x8369e78f, 0xada4bbf7, + 0xbd0172df, 0x6262db1f, 0x765448f3, 0xfb8f7ec1, 0x837280c2, 0xc81f1224, + 0x67b24d0d, 0x6b91d018, 0x8012cef3, 0x59a9d9eb, 0x517fd622, 0x37184e20, + 0x7c1a4971, 0x5e48205f, 0xfdfa3f46, 0xa26bf753, 0x05c99939, 0x7f782b86, + 0x4db4d8fa, 0x3e3dcf18, 0xc6f7f367, 0x8d3b7f42, 0xd2846f78, 0x3e703dc7, + 0xc0f5d0d4, 0xbcb66a7c, 0xb38cc693, 0x628a4484, 0xa3fcdbef, 0xaab26074, + 0x07975c78, 0xf2c16c7c, 0x3bed3cba, 0x78f03d1e, 0x1b9ba533, 0x166078a9, + 0xaf2097c8, 0x35ea4ff7, 0x1e5e293e, 0xc54af555, 0x6d3b3c4d, 0x08f3d768, + 0x329d3f94, 0x4e47c84b, 0x27ac6599, 0xf3616dfd, 0x3f105cef, 0xd02dfbeb, + 0x60f10e5f, 0xea2b853c, 0x0ee2a62c, 0x69cf0080, 0x9fc599b2, 0xf51f73d1, + 0x44a9f5a0, 0xffd1aef7, 0x3a51fde5, 0xb2f0077e, 0xc72bddf3, 0xd9b5ae01, + 0x8f40231d, 0x0cfe5ff0, 0x56b65eed, 0xb9b4f766, 0x0d9e64bd, 0x992a7be8, + 0x83e3105b, 0xcfe3377e, 0xd1baebf1, 0x63f16462, 0xc7ec5129, 0xd7f4656a, + 0x4df6f5c4, 0xf7a82c4b, 0x99094a6d, 0x955fd261, 0x573f54ce, 0x2a63b705, + 0x7b415e3b, 0x4e09090e, 0x2e296bf0, 0xe55d2746, 0x3fcf11b3, 0x882831da, + 0xd1e3bdf9, 0xf1db65af, 0x8040c35c, 0x83f30b53, 0x0eeddcd9, 0x3b47df58, + 0x7d60394e, 0xb80c3be5, 0x27d0f2ee, 0x620af369, 0xf049bd74, 0xfaf3c15d, + 0x46b59d0a, 0xc768fb4f, 0x6d7369a7, 0x730a4f4c, 0x706f417b, 0x2f1952f9, + 0xc65c2858, 0x751d9839, 0xf7c453dc, 0x386de232, 0x4f6f6b5b, 0x6af3b0b5, + 0x0dc9859c, 0x7ad0d6e3, 0x7c618788, 0x1ebe29cf, 0x57a32079, 0xf8fc6d3b, + 0xb4441be7, 0x26ac56a3, 0xff3d6768, 0xf46c81fc, 0x903cee6b, 0x5f53473d, + 0x6f8c3f8d, 0xf1616d9f, 0xa7f1a41f, 0xe20d251e, 0x7378d83d, 0x2007cabc, + 0x3b86909f, 0x1e38fa3c, 0xbd4d130a, 0xa7c40dae, 0xefd58a0c, 0x01dcff2a, + 0x5a736a71, 0xb413110d, 0xa70678f7, 0xebcbbc80, 0x2f77f7c7, 0x45a123c7, + 0x5ac93d40, 0xfa3e4510, 0x1134f9b5, 0x4d3e5a6c, 0xe324f7f7, 0xf0e3d1d3, + 0x19d813ee, 0x6b933ce1, 0xf5c8126d, 0x5e182b69, 0xa2207f45, 0xc435ddfc, + 0xf9522f52, 0xb0cace45, 0xb14aff01, 0x01acb8b0, 0xbf58f959, 0x1a679efb, + 0x4999e7bb, 0x8a7e30ea, 0x1f51db38, 0x38863fee, 0x580d0e41, 0x41911c98, + 0x830c1bdc, 0x7a3c9820, 0xf10151ea, 0x8e7c03c4, 0xa9ea0a88, 0x3f185f14, + 0xfa33e477, 0xf952f0e6, 0xa02ad0a8, 0x92db371c, 0x862bf5c8, 0xa3c2d757, + 0x3c62ffd9, 0x778ea05a, 0x12e478bd, 0x5be1f5c8, 0x1fc2761f, 0x845fb828, + 0xf0a771fb, 0x3628a67e, 0xb880af7c, 0xf1dd1d8d, 0xcd9fb464, 0xfd04de54, + 0xf62bb541, 0x62ea515b, 0x76b6e07e, 0xdface790, 0x7c5cf052, 0x05cb6c5c, + 0xcede3a79, 0x11367748, 0x533801ce, 0x1f94bd61, 0x5797fb30, 0x9d71fbc6, + 0xe21b8f01, 0x44880607, 0xcfdf3e02, 0x35ef8b90, 0xdd380bf6, 0x59dc182b, + 0xbb1e631c, 0xb12b5c0f, 0x075942fb, 0x1772c912, 0x5f4cc7c8, 0xcb8eface, + 0x78b52e0d, 0x225346ff, 0x7ea987b3, 0x69ecbef7, 0x9f4f41a4, 0xcbad5daa, + 0x537e174e, 0x0659ce0c, 0x85049f3e, 0x41ee4fdf, 0x35c00ae7, 0xff510c6d, + 0x4b3e4036, 0x14fe37cd, 0xae957bcf, 0xbd9d7b55, 0x736b9bc0, 0x7abb9213, + 0x8be031dd, 0xb8e7efd7, 0xfdd5e57f, 0x025dff1c, 0x9e7a0e7e, 0xb4c39776, + 0xe6ab39e9, 0xae12203d, 0x21cac7b2, 0x11695ece, 0x2575fb78, 0xde5c4877, + 0x3ee7f1c2, 0x3caaef06, 0xf1ba266d, 0xe293f3b4, 0x629087fa, 0xdfad4b9b, + 0x5bfa1138, 0x83e79237, 0x5f83d41f, 0xbea369e7, 0x6f29043f, 0x029a990f, + 0xc9f07fd6, 0x1a9fc741, 0xe1ef3b1c, 0xa97807fc, 0xf7aafee7, 0x44de34a6, + 0x3f3ab2c7, 0xf50778c5, 0xf4a7f6fc, 0x24e22f7e, 0xff5fe3e7, 0x761e841d, + 0x261693ca, 0xc90096df, 0xf9003d51, 0x17a97fb2, 0x9ca825e3, 0xb7cc21f1, + 0x338eddf3, 0xe7796847, 0xf78fcfb4, 0x7d6e3c03, 0x31e83678, 0xfa03b7e0, + 0x501b37f1, 0x055a55ce, 0x462d6f86, 0x7f1517a4, 0x7f1c9d2a, 0x7f788312, + 0x3090e9b0, 0x5445ec1a, 0x9bbecd3f, 0xd5b165ee, 0x31c70173, 0x533fdfea, + 0xeccad953, 0xe2fcfe56, 0xffd0798d, 0xf9c0810e, 0xc3ff26bf, 0xbfa8b9b4, + 0x4f36907c, 0x65a2aed3, 0x691f8b1d, 0x470af636, 0xfa606ad9, 0x1e7dc1dc, + 0x43e70be0, 0xca4b1618, 0x906ad0a5, 0x45cbcb57, 0x8546efd4, 0xbe43ef4a, + 0x2026533d, 0x5c587787, 0xd3cd1e6c, 0xe42f1083, 0xbf81ffa7, 0x7e77936a, + 0x3347ca29, 0xd5c41b15, 0xce2fcf9e, 0x5795fb44, 0x061c0276, 0x926537bc, + 0x149ef80b, 0xadb4b8c6, 0x2091b6b5, 0x83efadd7, 0x63693ecf, 0x782f5cfb, + 0x7e67df83, 0x5bb5a271, 0xf930b4e5, 0xe4cac32e, 0x867bf541, 0xb79dc995, + 0x0026db05, 0xda961c3a, 0xfaf720ad, 0xd013e789, 0xe6d7894b, 0x0f7089da, + 0x129ddea3, 0x4d3da170, 0xfc7f6949, 0x4dbf2826, 0x223b38c2, 0xe3033fb5, + 0x894eae76, 0xfc850bdd, 0x6f680523, 0x1beacc7b, 0x14e3a562, 0xf3b27971, + 0x10859de0, 0xe1ce38d7, 0xe824c9fa, 0xed0973e7, 0x8a9ee33a, 0xf8004db6, + 0xd9903e7d, 0x08e895b9, 0x9376b9ed, 0x9e93ad95, 0x92ef286f, 0xfbf237c3, + 0x1d9eb40a, 0x5a16f1ba, 0xb8de4153, 0xfd18f458, 0x24694c6c, 0x7d549f80, + 0x9282bb40, 0x872025e2, 0x4a96084c, 0x271cb718, 0x71e04c87, 0xf4a4881d, + 0xfbc7317b, 0xe1777421, 0x558a2dfd, 0xc7265ff5, 0xaeb792e4, 0xa3e090cc, + 0x8a88af2a, 0x1399ed0f, 0xc6085a67, 0x1e8cafd3, 0x9e2ec117, 0x0a7af942, + 0xf160cbde, 0xb32ff9a2, 0x466120fb, 0x3ffeddb7, 0xa8fd1da9, 0x7e56ad93, + 0xfc33d7ae, 0xb7186d21, 0xb0900940, 0xd6cf68fd, 0xfd5057de, 0xf27f6a86, + 0xad8f6672, 0x7c17f6e1, 0xdf9696f9, 0xb2ed556d, 0x467e75cb, 0xf0bedc75, + 0xc6aac2ab, 0x804b4453, 0xd507a31e, 0x4a4f8a78, 0x8cfa2f00, 0x5778e0a7, + 0x78f572db, 0xd195bf0a, 0x4f1d37c9, 0x913588f1, 0x11f44bc5, 0x471f114f, + 0x911999d1, 0xda4b5ed0, 0x7d04eeb7, 0x7e84c5bc, 0x6f2d29db, 0xcbce11fe, + 0x43090a29, 0x5cbc56dc, 0x5f4d35e1, 0x75def80e, 0xc056cce1, 0xef7775c3, + 0xb03f3377, 0xd7885e5e, 0x7cabb60f, 0x1b73cb97, 0x1fa7d7ad, 0x29bef5a8, + 0xcbe54eb9, 0x5187ae7e, 0xb9c072fa, 0x23d383b3, 0xd1c41250, 0xdd6dcbc5, + 0x1c9c7ef2, 0xd19eff11, 0x9d6f69a4, 0x61a47bc1, 0xa87100b3, 0xde0919af, + 0x63ee0dd3, 0x85b56dfa, 0xc3ea93f1, 0x2ca9fdec, 0xe3ed1793, 0xf22315e4, + 0xf9e57f0d, 0xfd114497, 0xdc00af04, 0x27e5a653, 0x5faefd40, 0xd50e901b, + 0x85b690f7, 0x2a74fc98, 0x94c88c5f, 0x79c1b7ce, 0xa13ce30c, 0x3d741bf7, + 0x31f18fd9, 0x5ae837ee, 0x9706fccd, 0x6033e3cc, 0x330ecaf3, 0xb7197ffb, + 0xf14aafff, 0xae8332fd, 0xc64ff16b, 0x1e75dda3, 0xd65a61f1, 0xc71bb7a0, + 0xbfccbdec, 0x78af0554, 0xcc05fbb3, 0x8fb1a7df, 0xae523bc1, 0xce18a906, + 0x5ce25ca5, 0x15d97c0e, 0x16fdd0a4, 0xbbf9eb4d, 0x802882c3, 0x4ead213c, + 0xac7ec0b1, 0x012717aa, 0x45eb05bd, 0x5bb88f7c, 0xd7e7e00e, 0x29ffce25, + 0x8e3042c8, 0x77f3d69a, 0x96fed57b, 0xa9023111, 0x9574b028, 0xdbd49a53, + 0x57f6a8b9, 0xc653ac6f, 0x4034be83, 0x25ecbb44, 0xe01333d9, 0x8f29297a, + 0xbd645c40, 0x1261aebd, 0xbf1c472b, 0xb17a8e64, 0x1312dbfc, 0x092b88d8, + 0xfcdbd9f8, 0xdb878edc, 0x3838c6bc, 0xe3f3d9c6, 0x88cb3ee3, 0xa0e6686f, + 0x6f92719e, 0x69733e73, 0xbfbf2e4d, 0xaeaee0c0, 0x067f597f, 0x4b007137, + 0x9e280e07, 0x303ffb09, 0xa04d8651, 0xd223b329, 0x07fce095, 0xef053b7e, + 0xb7cfc513, 0xc023841e, 0xbdecd5ab, 0xff3aaf8f, 0xddff79f8, 0xcce9c69a, + 0x5f780193, 0x3df194e6, 0x17d96baf, 0x705cb972, 0xd6a1fe2d, 0x07f806fb, + 0x1b578bd3, 0x13adbc78, 0x97bc08f9, 0x04a77f08, 0x9e08aef7, 0x79d5a1df, + 0x06d5aeb0, 0xc27e1f7c, 0xef9e1b74, 0xfbd987b5, 0xdb4b3576, 0xad9ce1b3, + 0xf7c76e2d, 0x0de1e36b, 0xfe5495b3, 0x49cdeb43, 0x1c6ef821, 0x79fbd069, + 0x3cb3fa7a, 0xd3e03645, 0x37aec8c6, 0x654338e9, 0xd7c858df, 0x02ee8d2e, + 0x91e3b579, 0x5e404af7, 0xd26f539b, 0x2792a7c5, 0xd2227ef4, 0x65768490, + 0x5effa4d2, 0x5dae39be, 0x2351bf0f, 0xd97ae3e2, 0x7be80c37, 0xd3f9839c, + 0xef88a549, 0x01db75fc, 0xe1ce1a9e, 0xeed3cee7, 0xee7d03ef, 0xef67ad2f, + 0xf77aef59, 0x2fec02f7, 0xbe6ad7dd, 0x7df617bf, 0xb7f60f2b, 0xf2b7cf63, + 0x1bd77f60, 0x3f403d1b, 0x0f9f153b, 0xefa73cfc, 0xa39ca2f0, 0x0b5c45c6, + 0x275d172f, 0xe6fa2e5e, 0xe7aaf2f0, 0xcaa6c05a, 0x5ced5f49, 0x9ead3f83, + 0x218af87d, 0x34bf4668, 0x3d98ffc3, 0xf077fcec, 0x0a2cb95c, 0xabe8f7e0, + 0xae5c51bf, 0x104850cc, 0xc54513ec, 0xe8aed8ed, 0xdc809173, 0xf179caa4, + 0x9f09f870, 0x4f36f3ff, 0x5f879c02, 0xce5aeed7, 0x4fa128eb, 0x43b9fc99, + 0x6bbb3370, 0x1dd5c598, 0x9d82752a, 0xd9885cf5, 0xb1f76b5d, 0x422bea77, + 0x5df0446f, 0x09c156f3, 0x8ec541fa, 0xeef01c0f, 0xae4e2690, 0x448ce819, + 0x9deceff5, 0x40729d0b, 0xb79d1bbc, 0x6b78e415, 0x7a06544a, 0xf1172da8, + 0x295ab3dd, 0xb5bcf18a, 0x241dc429, 0xf5ea5f20, 0x6c2e352d, 0xba465793, + 0xdecad4d9, 0x7d934ca1, 0x0f11fdb9, 0x6dfbe3fb, 0xb7edfd2a, 0xf800fe79, + 0x7ad3f31b, 0x8b576c5a, 0xc32ff91b, 0x617fe636, 0xccd97fe5, 0x6e3502e4, + 0xce8ff544, 0xf3eef1e7, 0xf83bbc79, 0xf81a236d, 0x9b56df82, 0xd5b6fd57, + 0x88322f10, 0xe5b56df9, 0x8d687edd, 0xae5b56df, 0xe889178d, 0x93234df8, + 0x310b0d77, 0x25d2864e, 0x579163c6, 0x88ced505, 0x74a7e9f4, 0x0c6464b0, + 0xf0fdd57f, 0x12b87f97, 0x3cfcf3e2, 0xf01ab2ee, 0x61c60477, 0x5fc04c46, + 0x355f14c3, 0x4b6a2efc, 0x7d7374e4, 0x37e8c8f6, 0xedf1df4c, 0xe3c7573f, + 0xb3aead74, 0x02ad5d7b, 0x75b8c3a3, 0xf189ebc5, 0xcf5569f6, 0x4bdf16bb, + 0xdf1f5fb6, 0xabfdeb53, 0xfdb65ef9, 0xbef7c39f, 0x47fffb29, 0x3034c6ae, + 0xe87b3e05, 0xd083df87, 0xad8312a4, 0x4c9477fb, 0xae3fe1d7, 0x437062d9, + 0x21cd4ddc, 0xaaf21bbb, 0x7fde323f, 0x94f64958, 0xfde3c800, 0x5710d588, + 0xfedae831, 0xb77b62c4, 0xfb573d5f, 0xb151785e, 0x61bf5f9e, 0xa7d934fb, + 0x02e2d3c1, 0x82f7e02a, 0x24148ab7, 0xa9f638da, 0x7eb7e676, 0x9fefbf83, + 0x88069321, 0x6eda7893, 0x14467bc5, 0xa62e306b, 0x6e9dead8, 0x9afc0d1f, + 0x83d9efc1, 0x0b8812f7, 0xc618d67e, 0x1ac13efb, 0x5727de1b, 0xff6a23ed, + 0xa97ea96f, 0xcd73e06b, 0xcd73e275, 0xf1cf8c37, 0xe3ab17ed, 0x61dfaf5d, + 0x06918503, 0xb3f1e3df, 0xf17d76af, 0xef765581, 0x91d23b72, 0x5eb9ef07, + 0x11e8ff2f, 0xf1b92987, 0x4dc41d5e, 0xfc559c42, 0x74f7a87e, 0x6b70b954, + 0x97a1fb9f, 0xc57eb707, 0x3c96b8fd, 0x0de2a4f8, 0x8f4f7ac1, 0x3e81e4f7, + 0xeccecabb, 0x0ccd9b2e, 0x0c0b372f, 0x13e07b1f, 0xe2a3efbf, 0xf5fb01d5, + 0x7ad43bd9, 0x78fe6aff, 0x2d7c2ed4, 0x69fc077b, 0x886c90f1, 0x7d767be2, + 0xfe9ec7f2, 0x5977162e, 0x517a86dc, 0xef8090f4, 0xf6f3ab33, 0xd63b31b7, + 0xd45c39ef, 0x1cb8fbef, 0xfcf0e398, 0xf10a9ec1, 0x8f028a49, 0x59028c3b, + 0x2f28e40e, 0x0da9378b, 0xda8fb8b3, 0x70e304a5, 0xb511fbd4, 0xc809532d, + 0xbecd0b6d, 0x55fb433f, 0x8682d9ef, 0x4fa3b004, 0x75a72023, 0x37f2cbbe, + 0x401f7d9b, 0x3b697fb9, 0xa69bfdda, 0xa138c79d, 0x5d3f2fa2, 0x3a5df609, + 0xa40bb45f, 0xd3f7f498, 0xc7c60e1d, 0x50ead4d4, 0x7b41ebe1, 0xfb950778, + 0xa7f2de40, 0x5f609c78, 0x56cded50, 0xe1da1b57, 0x6732f76b, 0xad81915f, + 0x9fda3c87, 0x8ef6d1f9, 0xe415fc2f, 0x9042e6c3, 0xb7de8b57, 0xe3a8fda1, + 0x138c2c91, 0xbbeacc78, 0x1f6af80c, 0xe40bba15, 0x0e3a1ccb, 0x7b1dadc8, + 0x79842aee, 0xe0a17d77, 0xccecbaba, 0x24f5d0bf, 0xcaf88999, 0x665dd1ed, + 0x9f022786, 0x666ad76f, 0xba1e0a9f, 0xdd03bf91, 0x38368f6d, 0xd1ecc746, + 0xa5407cf1, 0x08fbeeff, 0x1ff414b3, 0xbd61fcab, 0xeaa39d91, 0xeece77f9, + 0x3c16f1e2, 0x2a75aeae, 0x79e0d78b, 0xf8554f1b, 0xe3bb6f3e, 0x9cf3ac1c, + 0xdec7fa5d, 0xe24cbec3, 0x2fd8e7fd, 0xe36939c4, 0xdfe0add5, 0x53897b01, + 0x37b2bc46, 0xa1dfe610, 0xf9f20578, 0x09b6d16d, 0x839d7409, 0x01b7229b, + 0x165f0fbc, 0x53a0bbd9, 0x92f78b7f, 0xde360413, 0x57da27a0, 0x8afb050f, + 0xc36fedf3, 0x9d1abad6, 0x5b92e0c5, 0x870ef668, 0xd52241b8, 0xc578c3e5, + 0x3c5918ef, 0xda2b21df, 0xabb29a09, 0xbb691273, 0x684cf7ce, 0x03e789af, + 0xcb241a6a, 0x606f8e31, 0x0ed01fcb, 0xe82bdf6f, 0x93a6a6e0, 0xf7e6361c, + 0x6095b609, 0x296dc9ac, 0x0e6e77ec, 0x7f041fbd, 0x5f1ab4bd, 0x46f52486, + 0x7572088f, 0x7b411970, 0xa72690e4, 0xc395fb08, 0x0eba44e3, 0x1f08cfff, + 0xddaa9f9e, 0x64a9843d, 0x7a095f6c, 0xfdacb495, 0xc7ec20f6, 0xb6b144de, + 0xd68bfa00, 0x12b27c32, 0x5a739f38, 0x95bf2d06, 0x9c1a73e6, 0x7aea3fe8, + 0x0de30ab5, 0x439d7483, 0xa167597a, 0xdce5c583, 0xa520e3c8, 0xfc115643, + 0xb85ad2d2, 0x5341440d, 0xd29671ef, 0x129c43f6, 0xc38e7de2, 0xd4f00b37, + 0x5902f9ca, 0x9c7f4162, 0x6d78625d, 0x8bdef25f, 0x55bfcf10, 0x1d4fef66, + 0x34e37c3d, 0x96addfb4, 0xc6ab5ed0, 0x74e02e51, 0x47de13dc, 0xe0725e31, + 0xbf303fa1, 0xfa0b1d0d, 0x3f0c8c97, 0xf829d5a4, 0xc87fe07e, 0xfd0b8c3e, + 0x80c47d76, 0xe9e728fe, 0xaeb92667, 0xebc4b7ad, 0x891ccb29, 0x622e295f, + 0x3d9be399, 0x3fdbe24f, 0x55f78eae, 0xd7a210f5, 0x63e87acf, 0x5c7572f1, + 0x0ee4befb, 0xf542ee35, 0x504f1177, 0xcc526f17, 0xbe8a21c7, 0xef0b6abf, + 0x50a3c78f, 0xf205c439, 0xd70ada4e, 0x8ebf8832, 0xdfa098fe, 0x09978d46, + 0x9738b316, 0xbde0a8a0, 0x88d20cab, 0x48fd3271, 0x1ed01044, 0xd3b6e2c6, + 0xb6865e21, 0x8818ef5b, 0xee216ffd, 0x41f20306, 0xa4abbe17, 0xfdd055c6, + 0xd3243a41, 0xc13f1e64, 0x566b37f0, 0x70e2085a, 0x9f7edcfd, 0x7f1f2b35, + 0x3f135567, 0x33feecc1, 0x7d4f882d, 0x10aa53de, 0xd6253df9, 0x1710d36f, + 0x4d7ff3de, 0x693e6bb5, 0xe2e3ed67, 0xaa38542c, 0xfc2a1671, 0xf14c7bd4, + 0x79314c70, 0x57bc02df, 0x7dd425e3, 0x0d8fdeee, 0x55d82ecc, 0x1cbbe221, + 0x155d7f6a, 0xdc83679f, 0x626adc50, 0xefd712f8, 0xaefbeea6, 0x67c63321, + 0x96bd7df3, 0xdfbeaa1c, 0x23bf9475, 0xd7bf8c75, 0xc21665de, 0x399f8006, + 0xc9381b3a, 0xee4784f6, 0x5d817b84, 0xdc3668f6, 0x78dcdc2b, 0xa7cc24ff, + 0xfe424f46, 0xc3ff84b5, 0x5ba243f2, 0x89e19ee1, 0x1e58b3a7, 0x908b2e70, + 0x49848e33, 0xe07f82c1, 0xe3d73a5c, 0x022e1a77, 0xfb486b1c, 0xd3b436ca, + 0x146973f0, 0xa26463e3, 0x44ecc429, 0x13ffdc2e, 0x631dec99, 0xbdc0fe5b, + 0xdfde506d, 0x5a2df684, 0x627bf88e, 0xee5678c8, 0xfa4dfb62, 0x029c59db, + 0x13d33dff, 0x1fd1e3b9, 0x4df8035e, 0x462b85e5, 0xc740989f, 0xe1b420bf, + 0xee27593b, 0xe00161f8, 0x8ffd85eb, 0xe2b9060e, 0x77f7b94e, 0x72731ee1, + 0x7ec8c239, 0xa34de5f7, 0xf9409acf, 0xb3ad1fc3, 0xff69124b, 0xcbc79333, + 0xe0ef3089, 0x51eef8f3, 0xc4bfdf2a, 0x4bee4c19, 0x2015e89c, 0x3363f17e, + 0x1f54b3a3, 0xe2063dfb, 0x3ddc219b, 0x12d7235c, 0xc4113bf6, 0x7b804ae7, + 0x68eff108, 0x6b5e12dc, 0xf7f73900, 0x780ce881, 0xfefd5552, 0x38f7a107, + 0xc604828b, 0x5c19a6c7, 0x141f01c3, 0x29cdf1b1, 0x2bc6c4b7, 0xfbf17048, + 0x70a375c5, 0x51ba86dc, 0x28f4c7a0, 0xd072d1b7, 0xe5a09e93, 0x97297bc3, + 0xd67afb78, 0x938ef35e, 0xa974e01b, 0x2fbc03f4, 0x04eb38b4, 0xc27647be, + 0x0ef03c48, 0xfb93304e, 0x0739e8f5, 0x273c7dfb, 0x3b4fc591, 0x40704c37, + 0xffdb107e, 0xfd0848bb, 0xb06653bc, 0x21df597b, 0xb4edf56d, 0xfa199dde, + 0xcbb963df, 0x277fcfa5, 0xc29f9f5f, 0xebbe07e3, 0x1eff7fd6, 0x0f804a89, + 0xffa31fdf, 0x441797dd, 0x0be0094f, 0x2f8c27e5, 0x2aee3c0a, 0xf9c20845, + 0x2c81e37e, 0xc61a9ef5, 0xf5c0bdb3, 0x7fbf3f11, 0x91aa6701, 0x8586e3ae, + 0x1bdc9dec, 0x93928833, 0xf92bfc04, 0xf07bbe08, 0xa729f711, 0xf4789bc0, + 0xd713a97b, 0xf419e2af, 0x1f7c3b75, 0xe2e0cf9d, 0xd2538321, 0x418eefd8, + 0x6b2309d9, 0x84b1fc1b, 0x7d684e7c, 0x3e2c6ff3, 0xf184bc62, 0xd7ab0277, + 0x4ff86665, 0xfefc524f, 0xe21ede53, 0x27c89caa, 0x4abfdc2d, 0x8be85df0, + 0x78d8d2a3, 0xfa8b0f1c, 0x5bc01629, 0x7cbb5df5, 0x1bf6e127, 0x7069a64a, + 0xe794103e, 0xfd54bc54, 0x3c380348, 0x7f327e28, 0x1f872671, 0x06f7f091, + 0xcfda8932, 0xadc61374, 0x04bafcf1, 0xde2a6f46, 0xb5ec7fae, 0x5f00a737, + 0xc03f5c12, 0x3bb2ee7e, 0x74f9bd61, 0x804999ac, 0x78d829bf, 0xf449e707, + 0x247927bb, 0x8c5d8798, 0xb09a1b18, 0xbf7f307c, 0x4fa4fa6c, 0xfe1a4866, + 0x61adfb45, 0xfdf55afd, 0x459ba3c2, 0x68337e9a, 0x7e9a49bf, 0xf2c2689f, + 0xbfe5fbbe, 0xe7e92147, 0xaf8fb6a7, 0xf3f5ea4f, 0x7c7dabec, 0x14f7f53d, + 0x4df87326, 0xf329e356, 0x640f71f5, 0x7e615b8c, 0xc39c7d6c, 0x8edf1c9b, + 0x306dff5b, 0x09250be8, 0x2844a70f, 0x1a524c3d, 0xf408dbeb, 0xd0fa461b, + 0x802ff5d0, 0x7e652e2e, 0xb6fbbf80, 0xd989e078, 0x97a519d0, 0x7ba309dd, + 0xe7c547ce, 0x3c5179ee, 0xf1543c06, 0xdd9e7e38, 0x30bdfc78, 0xa16d7206, + 0xaaa407f2, 0x9d48423c, 0x0d70eb80, 0x2283ad88, 0x87528961, 0x22b37ff3, + 0x33bdf388, 0xff8c19f1, 0x3be49319, 0x799af302, 0x3dec27d3, 0xa1d28c93, + 0xf9d10720, 0xfd484d1e, 0x355f377f, 0xe1dc796e, 0xbd82373b, 0xe3ee9bb4, + 0x5fed5ce8, 0xf234d395, 0x2af73b15, 0xf2be5545, 0x19642900, 0xe57cb832, + 0xacd678c2, 0xf10dcb80, 0x8af91aaa, 0x44d547c9, 0xeece07bd, 0xa060fced, + 0x987abe5e, 0xb76ebc60, 0x271a557c, 0xede3cd5f, 0xc42092a7, 0x93d936c5, + 0x805e2c42, 0x162d39ce, 0x8db4dbff, 0xb74d8dc9, 0x82419cb8, 0x33d31672, + 0xe87bf166, 0x6bde4cb9, 0x77c98fba, 0xbaea1ce3, 0x6b78fa2c, 0x133567ee, + 0xb8b12f2a, 0x99abb40c, 0xa5d97d9d, 0xb53576f4, 0xf202ffde, 0x007f0832, + 0x00007f08, 0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0x73b9f8b9, + 0x64cacb67, 0x109848df, 0x424e3b08, 0x875b3612, 0xe22948b0, 0x3cb888b0, + 0x4240b21c, 0x3eb44196, 0xc33fedad, 0x0d220222, 0xc168d46d, 0x2a14180e, + 0x0431a0d8, 0xa4587049, 0x141a87d0, 0x2f1f682d, 0x48145840, 0xad88a0c6, + 0xbefbffcb, 0xef726e73, 0xf6b42264, 0xfa7fb6ff, 0xef7397b3, 0x6df3be59, + 0x39ce5be7, 0xd78deec3, 0x1ec658b1, 0xacc630b4, 0x98eb458c, 0xb19436b3, + 0x96eff0ef, 0x95e5e7ae, 0x6289e63a, 0xa31574ac, 0x47d7e5e7, 0x7a83cfa6, + 0x4c8c7697, 0x66e783cf, 0x92d433b3, 0x50e158cd, 0x2fa18a7b, 0x7b46f963, + 0x9b19933a, 0xbeb45e64, 0xcc9eba19, 0xd393f516, 0x5b09fb18, 0xcf074c74, + 0x48ce9151, 0xc8673fac, 0x287a2967, 0x0379f8b3, 0xfd8c611c, 0xc28f675e, + 0x19b98cf7, 0x718535c2, 0x4398a6b8, 0xf870f2bd, 0xa5c340f7, 0xfe8c8196, + 0x1c7183be, 0x4b6f6726, 0x1155630c, 0x67971fb5, 0xa35cf631, 0xe2b6e6c9, + 0xec1496d7, 0x11deb18f, 0x043086e7, 0x543ce185, 0x39e814f0, 0x4cb2d13c, + 0x040bf4f0, 0xc65e630f, 0x68e0ba72, 0x94ae8437, 0xb1e0a97a, 0x00d17eb3, + 0xc7be24a7, 0x06895ab1, 0x6a5383f3, 0x1257e3fc, 0x33d38fd4, 0x63265877, + 0xea97981b, 0x1ce75efd, 0xb3c6e381, 0xb8e1894a, 0x112b6c2b, 0x96e0dd4f, + 0xbf30c901, 0x1ec977d9, 0x0ae60c13, 0x7ace1f09, 0xd4fb3d61, 0xba7f1804, + 0x2af67f18, 0xac0884c7, 0x78e25d37, 0x00ffc2f0, 0xfbe219fe, 0xa9b2c6f4, + 0x3198e00c, 0x13ba70c1, 0xa66ff83e, 0x0181ba65, 0xc2a6b39c, 0x7bd7737b, + 0x61d2209c, 0x2cffd28e, 0x6c39bb6d, 0x387267cd, 0x10191696, 0xd5ee735f, + 0x09669f7e, 0x42173e8b, 0x077c076d, 0x60603af3, 0x79f68f34, 0xe609b3cc, + 0x82cc56f1, 0x3347f7f5, 0x43b7e036, 0x7fe86533, 0xcd716c62, 0xf4bf283a, + 0xbf2a60dc, 0x83cf7b15, 0xf3fbf147, 0xa09e54e9, 0x6e504683, 0xb3ce99ff, + 0x9cd01529, 0x5494d773, 0x9040ff18, 0x467ef7e8, 0x9d83e3ef, 0x5ea1d355, + 0x99bef0fc, 0x04d3e0cb, 0x0aede323, 0xde9ff7f9, 0x9ce54614, 0x191eacfb, + 0x6c109cba, 0x30f7d375, 0xaa09b6c9, 0xd130c91e, 0x53e361f7, 0xccbef7f9, + 0xe7df851e, 0x23fb5185, 0x0b5e2199, 0x47f2f78c, 0x01fbe883, 0x0eb9b3e9, + 0x595b5120, 0x52e91ea8, 0xe336689e, 0xc940c873, 0x3df0083b, 0x5f8c5221, + 0x353de7c6, 0xca226b73, 0xdf5c84cd, 0x6850c75c, 0x670e6897, 0xfe1f1137, + 0x8879f90c, 0x34aadc6d, 0x5f16afe4, 0x150f9a8a, 0xf8574f3a, 0xcf96826f, + 0xc51e7e40, 0xfa9f0af6, 0x87c2a7f3, 0xea0b3e1a, 0xb97f33e2, 0xd7009e57, + 0xb18f924a, 0x97721f20, 0xe38e747c, 0xe3fe2727, 0xf8bf24f6, 0xdca2c527, + 0xc2777f88, 0xd0f24b57, 0xb9e9b99b, 0xcb83e501, 0x8708b3cb, 0xc56cd751, + 0xdb247df7, 0x33c20b60, 0x0c7666ca, 0x0a372eeb, 0x783ac97c, 0x2e1dd991, + 0x3943d3fc, 0x45fe7589, 0xb8e0e747, 0xb3b43bfc, 0xb82ec8b3, 0xa4adfc60, + 0x7870569f, 0xb88b4836, 0xd09763bc, 0x5768b94f, 0x41b7ccae, 0x0678df3b, + 0x2ffa8778, 0xc4967ec4, 0xfe18dddb, 0x82b87995, 0x4f81ee41, 0x611d9966, + 0x1dd39846, 0xb724f911, 0xebf73277, 0xb38f8011, 0xc2136706, 0xae643c77, + 0xed7e1191, 0xf757a146, 0x74285f20, 0xc7f4e052, 0x7a0f794f, 0xfe1e7fcd, + 0x57a2e978, 0x133e0273, 0x2b2a22d8, 0x79e1bdf3, 0xae5e0ff6, 0x69bdf983, + 0x147c9df0, 0x6fcdebe4, 0xeb3736cc, 0x20cdf382, 0xbc3d12eb, 0xd992ff77, + 0xb3e00736, 0x051f8168, 0xb32e772e, 0xcebeb19b, 0x8a9659ec, 0xe06af674, + 0xcfe88fca, 0x7f174c58, 0x5eeb31c5, 0x2afb3154, 0x3d56b6ec, 0x57a487ad, + 0xcf50c2d8, 0xab9f6866, 0x99c4e5e7, 0x50a59eb1, 0xdce8f76e, 0x3c6f1806, + 0x347375e8, 0xefe74fbe, 0x38230b59, 0xc20b3147, 0x90011559, 0xbbaaf7c2, + 0xd1c03dd2, 0xd95bfeac, 0x7ddf041d, 0x0fa4c1c5, 0xc16032aa, 0x83efc2cb, + 0x896efbe9, 0xd62ee38f, 0xd355b8d1, 0xeaa8feb9, 0x53b8f16f, 0x54ceb271, + 0x8daaf7e4, 0xd04884f6, 0x5b328923, 0xa47a0b54, 0xf0ca152a, 0xeec65d8c, + 0xf4c47d43, 0xc3d3e1f6, 0x78fbf0ba, 0x11deb8d8, 0x84b71fc0, 0x96fe75f3, + 0x2af9ccb5, 0x29b563d6, 0xd57587d3, 0x00008a8b, 0xd4305eb0, 0x596efe83, + 0x6286f50d, 0xac2f507f, 0x83763d7b, 0x68a7c476, 0xac608c47, 0x9f11d858, + 0x8299dd6e, 0x9b27c476, 0xa9e4a677, 0xd8945fea, 0xbfd71c1c, 0xbc656f7d, + 0x66ec67ca, 0xa0926f18, 0xf98724fb, 0x50eb8494, 0xe77b44fc, 0x1a7c85fa, + 0x0235bf61, 0xef9061f5, 0xb47ba445, 0xf90e77d1, 0x6261bd8a, 0xa3ae199b, + 0x1a5d72be, 0xf7876faf, 0x1bc8efe5, 0xdb7e0357, 0xdbfe3862, 0xbe041976, + 0x2dff9e5b, 0x0c34af94, 0x3c61ab60, 0x0231bc17, 0xd71cbbff, 0x853d702a, + 0xbfce333f, 0x57112854, 0x55d98983, 0xfc1b60eb, 0xc5d99457, 0xd04ced2f, + 0xe88421b7, 0x1b372e5b, 0x75caff91, 0x70875d92, 0x59ec1c2c, 0xa7e97526, + 0xe8af4512, 0x132972d8, 0x262cede9, 0x9827bcbe, 0xfdf0966d, 0x80c5f4e9, + 0x9af352af, 0xa18f5c66, 0xd70901de, 0xb407a41c, 0x53ed885f, 0xbcb3e3bb, + 0xad54e00e, 0xb4dba5f7, 0xc6642f70, 0x0784efae, 0xd7cbc937, 0xc414e706, + 0xb730596b, 0xcd4b2e43, 0xf03f0839, 0xf017b79d, 0x2649afa9, 0xc0c426be, + 0xbe8a79f8, 0xdc7ce6a9, 0xb3c7d55e, 0x09e7be04, 0xca35e5ba, 0x0b3c135e, + 0x5a7bbce3, 0x2d4addb0, 0xfbc74b1d, 0x3952ea0e, 0x1ea38e1e, 0x4dc152af, + 0xa7054e7a, 0xa25cbddc, 0x7d45eef7, 0xc63f3fe0, 0xeba935be, 0x4ab689dd, + 0xe709f236, 0xf495667b, 0x0797d066, 0x4ca15d05, 0xe62499f3, 0xf5f23466, + 0x14ef9fdb, 0xd08eaefc, 0x8eba3971, 0xbe412dbc, 0xbcbeb98e, 0xb3fef529, + 0xdff56de4, 0x06ec6f29, 0x8267c1d7, 0xf8083b98, 0xd8ca5ab3, 0xfab27a8b, + 0x465b6636, 0x37ebb55f, 0x088673ac, 0xc035fd7c, 0x85987403, 0x9d7906ff, + 0xad3f7d1d, 0xfc97607b, 0x9cd9f516, 0x776ec201, 0x2424bb70, 0x9b19f38b, + 0x61fd3cc0, 0x1ca2610a, 0x23d9b932, 0x1eb91f03, 0x006765ce, 0xf8fb311f, + 0x32f5f2fb, 0xe51375d9, 0xa865d8bf, 0x659431db, 0x5cc80582, 0xd53f4417, + 0xa633f512, 0x24fee371, 0x6e4c4728, 0x7016464e, 0x6674bc3d, 0x9c0208eb, + 0xd058b1e8, 0xdfe1f163, 0x67c5bd50, 0x7d827979, 0x57942f60, 0x799921d7, + 0xa1c761a0, 0x2f2c7a99, 0x28b125d8, 0x104cf718, 0xd501a397, 0xc955663a, + 0x304f20e3, 0x75f8aab3, 0x4d4896c8, 0xa26d5879, 0x0d4dfea6, 0x33df357d, + 0xdf3583bc, 0xd4ca1c47, 0xc79bb394, 0x3c8fea68, 0x8f29ab9e, 0xa9a2996e, + 0x0cc2f63f, 0xbe47f94d, 0x99f535bb, 0x103cdedb, 0xe82050f0, 0x8a0ff8af, + 0x5ae5bafe, 0x2c3da69e, 0xe8095ec7, 0xb15fc85a, 0xc80b3582, 0x2d07193f, + 0xc896fdd4, 0x8da20e6b, 0xf5a95856, 0x6b54164f, 0x1b0dc5cb, 0x5609408d, + 0x2fbed1ec, 0x0f2da2d9, 0x43a79e88, 0x011b3abe, 0xf820c9fe, 0x428b1447, + 0x2ec9eff9, 0x44efa7f1, 0x00758fe1, 0x7e8098df, 0x33dface9, 0x7d234737, + 0xdf03cc0d, 0x7e05b03b, 0xf5c1be07, 0x03d0e3a3, 0x8523e43a, 0x3278fede, + 0x1ee96bc5, 0x3dd2d564, 0xee96a064, 0xdd2d3661, 0xd2d28d7b, 0xa5aec23d, + 0x2d64d47b, 0x5a1c63dd, 0xd1cdc7ba, 0xa9c13dd2, 0x91527ba5, 0x8bc9ee96, + 0xf3ef74b4, 0xa9ae96b0, 0xbe5a85ee, 0xc503e3f0, 0xb95b4b4e, 0x8e9eafd8, + 0xe0fcd4e9, 0x40ca9a28, 0xfcaff4cf, 0x7fffa6b9, 0x45a43f36, 0x92353f0a, + 0x7e477e45, 0x645fbd86, 0x46ff7776, 0x7f6a6bd1, 0x65d39f42, 0xefa4f67f, + 0xd3cbd9ba, 0x47a09c78, 0xdc9ad97b, 0xf5272f65, 0x982797cc, 0x4bd689bb, + 0xf08746b6, 0x70e165dd, 0xa357c15c, 0xd59bbb19, 0x13dfb01a, 0xc0146750, + 0x03e7027b, 0x9acbdfe3, 0xe65cfde9, 0x5993a7a3, 0x63ccf88c, 0x30167a36, + 0xe8a73d07, 0x1e22b79c, 0x392dcd4a, 0xceaf6fa8, 0x42527a3b, 0x21448ea0, + 0x2f23dfd0, 0x4ea75a6e, 0xd999cc57, 0xd6b18fda, 0xb44ce70a, 0x16e33ba7, + 0x568d6676, 0xbc6f2de1, 0x7a8f5034, 0xa1b60e56, 0xa777943d, 0xde6cf644, + 0x3739fc97, 0xfe43af92, 0x2b0f65cf, 0xfe14ab78, 0x1e43f707, 0xbb0ab48e, + 0xc943399e, 0x7059b3be, 0xb8fe805d, 0x9182ff3d, 0x82582eec, 0x2e80d7f5, + 0x4f4e24db, 0x4dda2ba4, 0x7cccf4c3, 0x9843ca0d, 0x27ccfc93, 0x7892a0f4, + 0x1fb1833f, 0xa0dbda17, 0x75234a02, 0x8e394e34, 0x3cd4f007, 0xaa20cccb, + 0xe98126ac, 0x9afb4207, 0xf12ca225, 0xbce1fe32, 0x454cdfc9, 0x4d2b6d78, + 0x4858af64, 0x4ccd923e, 0xe3dc91c4, 0x493ef0dc, 0xed090d06, 0xbfc01bd6, + 0x6b942488, 0x2198c3e6, 0xfaf99ce2, 0x934c157e, 0x51f8539d, 0x0a2f7c26, + 0x1dbfdeb4, 0x9595edc9, 0x40efc715, 0xcdef297a, 0x84b3377a, 0xf7825ea2, + 0xeb31b92a, 0xb0f11d99, 0x533dc2a2, 0xc8d9ff5d, 0xf1e7ea48, 0x4e2d8bde, + 0xdf723ef8, 0x720428a2, 0xd9739067, 0x10a1658f, 0xe9458962, 0x069ad46f, + 0x1ec3fb99, 0x919afd19, 0xd4e7f5c7, 0x2dd1a471, 0x0bd8f2da, 0x0f42b2da, + 0xc177f376, 0x82650728, 0x00f14caf, 0x195eaa97, 0x67c0f63a, 0x0fdcf165, + 0x84c1be63, 0x1b90a377, 0x0de49d53, 0xc130f902, 0x0a61925c, 0x9ccc0c2b, + 0xedeb7480, 0x6e5da0b4, 0xd0ebd44c, 0x2ff2603f, 0xf800ce6c, 0x78a69e53, + 0x7eb555fd, 0x17ea03f9, 0x48d86bb0, 0xdff11236, 0x41e02f09, 0x1a3a7802, + 0x46ae36e2, 0xcdcc9c78, 0x613603cb, 0xb3fea7b9, 0x7a59becd, 0x0b6cc110, + 0xbc3fc67f, 0x447e9674, 0xa3af7af7, 0x64e3075d, 0xd93db8eb, 0x8e5cde9d, + 0x6bb3e93a, 0x01646c81, 0xb0d553e8, 0x7fd4e3ff, 0x25793e9c, 0x51e22ba9, + 0x6fc092ee, 0xcd698787, 0xf8009612, 0xc75aac2e, 0x092e3f90, 0x8f325c38, + 0x24d7b1c3, 0xb5e8a7aa, 0x10022c97, 0x875a1af3, 0x62f04407, 0x0eb72f7a, + 0x6bd2f2e5, 0x2fae88bd, 0xf1474efe, 0xa3cc41b8, 0x610cf9c3, 0x8c3efa5e, + 0x26f950b5, 0x67281514, 0xdbf12b30, 0xbb23e608, 0x2b5cf411, 0xd972b9ea, + 0x2820bbf9, 0xbe764e5f, 0xe84e7a44, 0x4fc174fd, 0xaf7e8ae9, 0xddc7fbd6, + 0xf8a48d3e, 0xad0b6f4a, 0x54ce4223, 0x3af82674, 0x7f91448e, 0xe768e209, + 0x544db4e5, 0xc688303e, 0x587c1429, 0x8d88ec98, 0xc5ebd154, 0xf5336b8a, + 0x7802f92a, 0x5bbf28ec, 0x4d66822a, 0xa397bd50, 0x32071e38, 0xa18fd5df, + 0x2175f9ff, 0xe047b436, 0xf97ec68d, 0x4729c90f, 0x5b97bc01, 0x9a3af5ac, + 0xf50ea567, 0x24efd962, 0x33c01cf6, 0x66b97180, 0x7035e2fd, 0x9848a96d, + 0xf9f40135, 0x0fdc917b, 0x1c7cc971, 0xe28433b6, 0x8cc98531, 0x853f4385, + 0x7c91a7af, 0x0bd0c40d, 0xcc32b1c2, 0x8c2f7683, 0xdd95151b, 0xf1ff1e1d, + 0x35df43df, 0xb733f49b, 0x1ef543bf, 0xdd9973f4, 0x7bc7556e, 0x19bb0b56, + 0xe39213fc, 0x3b9fd160, 0x7aff7197, 0x84fb8f30, 0x296ae6b2, 0x62f5e7ad, + 0x9a651a20, 0x014c02f5, 0x36ce5718, 0x16ae5c93, 0x47acc472, 0xe18fe8ad, + 0x3a184673, 0x8f0e9cfd, 0x1cfbb187, 0x24fd7a2a, 0x3f0baf8a, 0x6a78e289, + 0x077b7337, 0x2a19f5e3, 0x31af387f, 0x251bec9f, 0xec2edfbe, 0x9503f6c9, + 0x27e8c1b9, 0xbe388a57, 0x058a9fb0, 0xfa682d2b, 0x4ad78e4d, 0x3e91587d, + 0xfe7de2f9, 0x535dad4a, 0xf649c5b8, 0x24ecf5cf, 0x09c514c0, 0x49a4edfd, + 0xd96f4251, 0xefc60658, 0x3b49accf, 0x307a8c18, 0x1e305995, 0x9abf249f, + 0xf11428b1, 0x871cace0, 0x4f543df2, 0x67afeb72, 0x1a87041e, 0xe245b9e9, + 0xe7f774f4, 0xd92db4f1, 0xb2dcefdc, 0x7f5a63b7, 0x58cbe7e8, 0xdda52f8e, + 0x6a06b197, 0x38e828f7, 0xd8cb5f7c, 0x6e7e40e4, 0xc977c091, 0x7a8b2096, + 0x8dab2a7d, 0x0d5d94d0, 0x7af51609, 0x2c28f640, 0x4c146caa, 0x7e2ba721, + 0x72d0d653, 0x768ac430, 0xca017381, 0xbfc1fb49, 0x3a250f86, 0xff5072f8, + 0xf9c7183d, 0x02b6e113, 0x9f743b3c, 0xffd355cd, 0x80bd28d1, 0xffa7af9b, + 0x2d765c30, 0x1e87975c, 0xe1c29d8b, 0xd5c239fa, 0x8b1d3de6, 0x8cb805f4, + 0xe476b86a, 0x3f9ff8f2, 0xa1fc9e9e, 0x88f564f0, 0x87df35a7, 0xc0c61da7, + 0x74126cf0, 0x6e80f97b, 0xfac027b2, 0xcfc849b4, 0x1aef0c3f, 0x6b6dfc3f, + 0x15618d9e, 0xe1137780, 0x9635be2f, 0x7f021672, 0xe04e22b5, 0xc6fa12ce, + 0xfd03ba06, 0x7a468fba, 0xead40f50, 0x2c54d459, 0x96d814e7, 0x46af3cc0, + 0x5da0fb38, 0xfe21eae4, 0x7f8091f2, 0x7014a247, 0xef881ffe, 0xf5e48f7b, + 0x89ff75c1, 0xf28626e3, 0x09ebe0af, 0x1339ad4b, 0xe6fa37fb, 0xf59cb0db, + 0x1a1ad9b9, 0xef1d7fa0, 0xf27e57ff, 0x3caff4a1, 0xc81a8ddf, 0x01d247e3, + 0xfb209419, 0x9ac7cdd5, 0x7f9cc3c7, 0x9d27a595, 0x79e30ffa, 0x79fe36b9, + 0x762c7bd9, 0x778be71a, 0x4b97df51, 0x876fc367, 0xbdf24bb2, 0x97f31433, + 0xd7cd2746, 0x6d8991f5, 0xbce7600c, 0x9942f821, 0x057f329f, 0x151fb0ee, + 0xee0091f4, 0x5a2613b0, 0xf5103e0c, 0x97a07595, 0x5e71a3b0, 0xacdc0eb4, + 0x6ca071e7, 0x57f7d13d, 0x1c50c6a3, 0x27c88768, 0x291b46fa, 0x870fe95e, + 0xff8f9a21, 0x9bf7b5c4, 0x8d3f62fb, 0x33e78a06, 0x4cfc4b7d, 0xdbd717e0, + 0x9427877a, 0x8ef266f8, 0x4763a450, 0x753c0b78, 0xa76a06d1, 0x7287bd43, + 0x8c9e4d71, 0xc8fdae7a, 0xc55916e7, 0xccb472e7, 0xb9ac6be3, 0xbff42c79, + 0x30599336, 0xd62a1cbe, 0xad23d0df, 0xe87f0845, 0x249b9fa8, 0x4af6fc55, + 0xadda8994, 0x6d62fa35, 0x09ab9fd0, 0xf78a051c, 0xb1b118b7, 0x85970782, + 0xeb3ca1e3, 0xe866e800, 0x4760d1a7, 0x2b68e578, 0x7700a7d7, 0x1e0fbc3d, + 0x1f25b9f4, 0x78c167bf, 0x87dabb7d, 0x833d3859, 0x439e61b3, 0xb3de5f91, + 0x97b3c014, 0xdf081cc4, 0x3f5cd183, 0xc455702b, 0xfc02fd71, 0xf114321e, + 0x7ca3ac9a, 0x66fae3ea, 0x96e3dfc2, 0x8c25967e, 0x79c76ef0, 0x299b46f9, + 0xed1d56ee, 0xf9c6898c, 0x1e1cd818, 0x8c766cf7, 0x32587c27, 0x07002356, + 0xf0bd9106, 0xc38bc133, 0xb21cf358, 0x168cb20b, 0xf594475c, 0x8ede8bf9, + 0xcd37685e, 0xd076e68d, 0xd742b7f9, 0xc0abbae0, 0x2c02b677, 0xb957633a, + 0x8498e6d0, 0x9ccf9978, 0xe78e502b, 0x551e0157, 0xc0de7efc, 0x16bc2dfb, + 0xaa51bccc, 0x36eea376, 0x6bc2bb62, 0x760bcce1, 0x5e20f9f7, 0x5f187cef, + 0xf18ac6cf, 0x33fc156f, 0xea07fa33, 0x7c9f9b31, 0x8bf3f86d, 0x8d8f5c79, + 0x4995bc45, 0x7bb4462d, 0xabf98ed7, 0xb3e9ed11, 0x4de61615, 0x4679beff, + 0x9c6aaf31, 0xccd77ace, 0x3ca51f34, 0x5b24f917, 0xc250df3d, 0xf88ad9c3, + 0x4931e0eb, 0xfeaec783, 0xd8f06afb, 0x1a74ffbd, 0xc0c56cff, 0xa43ff4eb, + 0x1aadfe87, 0xedfabbf8, 0xedb6e347, 0x04297bcb, 0x779f7bf8, 0x31bb73e9, + 0x64c7bb1e, 0x373ca131, 0x3f22e6d4, 0xbc0edd5e, 0xd0f4fc04, 0xff28af9e, + 0xa326d0f8, 0x3768c70d, 0x02dae6f8, 0xcc7eefe8, 0xea8dd6e2, 0xa746167a, + 0xdffd9d11, 0x0b1ef59b, 0x03cd95c6, 0x375c16f5, 0xb3d9accc, 0x4cd7f894, + 0x3f8944fa, 0x8b4efd28, 0xccfa3592, 0x5fd9f425, 0x9047cef5, 0x5f3aedde, + 0x89da1e7d, 0xb70f3f03, 0x41117f92, 0x3f12ba76, 0x892383d0, 0x3989ad76, + 0xde4de618, 0xa3ba758e, 0x82dfbfa1, 0x411c62b8, 0xc4e3561e, 0x2293fb78, + 0x5064ffee, 0xa54dbc73, 0xeb45d697, 0xb09d987f, 0xb35f8fd2, 0xcbd17c3f, + 0xc47583d7, 0x2bf372af, 0xb58bbf08, 0xc55c7918, 0x5e67f64a, 0x94e3c1d6, + 0xacfc520f, 0x05fbfe95, 0xbfd02392, 0xe11de252, 0x9ae2ace8, 0xd68c36bd, + 0x5e10fceb, 0x28b7ffce, 0x8a819fca, 0x6ac43d26, 0x162f9e65, 0x310e9671, + 0xdaf37687, 0xda1ff414, 0xa3ab1e45, 0x46e83f71, 0x4fecae78, 0xf37fcf74, + 0x9f6869d1, 0x79e33e83, 0x5a30a6ab, 0x624df227, 0x9106279c, 0x9123b17f, + 0x7ab57fdb, 0xcaa6786f, 0x77bc7c1e, 0x685f736e, 0x7f656977, 0x5dcbda1d, + 0x0efbcdfa, 0x39dae7f6, 0x574df888, 0x39e9e83f, 0xd7489718, 0xdcebb0d9, + 0x31eaaffa, 0x16b650de, 0xef1801ec, 0xa469e812, 0xc4feae93, 0x705f5c70, + 0xcb3f5c6c, 0x9fc893ea, 0xd1f10fcc, 0x60b293fe, 0xea05ba5b, 0x4d8fd7e5, + 0xf33fbe47, 0x5c14a0e4, 0x58c74e0f, 0xdc4f3053, 0x192024fe, 0x69ba79e6, + 0x6abf7f00, 0x17d470e4, 0x9c436b61, 0xadfc009e, 0x95fcf7e8, 0x14767226, + 0xcc48ef3a, 0x7c406b68, 0x7e93320c, 0xf6450507, 0xdf21fe53, 0x17786b0c, + 0x473f159e, 0xa15ac7c1, 0x3ffe954f, 0x79517a16, 0xd299fac2, 0x31ef7082, + 0x1ccffd11, 0xc38d7bd1, 0xf1b21ed1, 0xd08556f1, 0x0730f978, 0x29cbc80b, + 0x8e9d8eb1, 0xbc470eb4, 0x2832ebe7, 0xe443ba0f, 0x7c5956e5, 0xe41eb8e1, + 0x194ad9eb, 0xbe62afea, 0xf8d508f0, 0xd7b28df9, 0xfbddf448, 0x4d5ff90e, + 0xabe90c61, 0xfc8c337b, 0xa69bd773, 0x018f684d, 0x6821ddfe, 0x91371e17, + 0xc9afb2df, 0xfb617644, 0xd7f21089, 0x42c3f1fc, 0x3f48297d, 0x44499bd7, + 0xdf64f6df, 0x0c8edcf3, 0x680f9862, 0x891cea3f, 0xd1694274, 0x9ec3e3c5, + 0xd5cd7680, 0xda2f20a6, 0x60f4f035, 0x6acdd07c, 0x9efde9e2, 0x347e8610, + 0xa8643d3c, 0xe0f17549, 0x1082a0b3, 0xfda99bed, 0x01ce2943, 0x4a1f1fa8, + 0xb143fe83, 0xbbd52b7d, 0x9379d7da, 0x1221c785, 0xd48978c5, 0x5fb7326f, + 0x8d39f499, 0xef89fd03, 0x65ddf4cd, 0x79a48e72, 0x36c61c7c, 0x61679806, + 0xa0bcb6a5, 0xf62e5b5a, 0x5b25cb68, 0x745f65b4, 0x814fd114, 0x7f73e15b, + 0x70c4a4bc, 0x87c142bb, 0xd2769f3f, 0x61f03af3, 0xcbf1013c, 0x571d391a, + 0x929aba0f, 0x0f2de387, 0x9753e4d6, 0x3e279d34, 0x9fd8376c, 0x77c075c1, + 0x9136c0d4, 0xd50360fe, 0xf8ffb6fe, 0xe7adf3dd, 0xbcf5be45, 0x26dadf26, + 0x160c2ef4, 0x5084f18e, 0xe11c359b, 0xad4ba1d8, 0x3d5f22f5, 0xbe7c4419, + 0x21cbf716, 0x401baddf, 0x054452f0, 0xf0b3cfc6, 0xfd08cff1, 0x54c5e677, + 0x642d33ca, 0x4b4fa4b5, 0x44bef399, 0x5887e78c, 0x57ff9073, 0xcdfb02d9, + 0x27baf8fe, 0x34e3d386, 0x7d8ac6b3, 0x6fcc564d, 0x80bfe114, 0x74fd4504, + 0xdfbe20f6, 0xd175f48f, 0xd481137a, 0xd8ccf7c9, 0xf3ff9655, 0x0d0077cb, + 0x3655fe11, 0x67ae3877, 0xde7c2c17, 0x91593f60, 0x9f3245be, 0x8875fa07, + 0x2f120bc7, 0xd942fa2b, 0xdf00b12f, 0x989e7ccb, 0x518f2fa7, 0xc7ae38fc, + 0xf75e925c, 0xd693e830, 0xf2386b08, 0xb4aaeb53, 0xb79825c8, 0x66c6b088, + 0x3aecf0aa, 0xd026bcc0, 0x0946d65f, 0xf0ddbf63, 0xf39223b5, 0x085d6fa3, + 0x8eaf2bad, 0xf6ab996b, 0x8635ff13, 0xc58f91db, 0x16a6ff70, 0x40ec826d, + 0x5a74e078, 0xcab4e820, 0xf931fce6, 0x16f57e4b, 0xf412f754, 0xb95f7bf3, + 0x2f295ffb, 0x0fc55eb5, 0x8a4edeb0, 0x385de3e5, 0x374b7464, 0xfb4a5f91, + 0x82eb7c9a, 0x70bf6ec8, 0xae3a4a68, 0x82eb4543, 0x155f5122, 0x8b135e1d, + 0x8db8c8f6, 0x3ae2c58f, 0x6269b055, 0x9fe2533a, 0x482a3e2a, 0x3da3a7b1, + 0xb6567be4, 0xd5453f60, 0x4ab5c132, 0x167e695f, 0x36ab9fde, 0x24549d90, + 0xdbd73ae0, 0x2f788e19, 0x11bd33d2, 0xef4e7ef0, 0xf03b270c, 0x2ffc9959, + 0xbd40f9ff, 0x00ccfa63, 0xfa0b3278, 0x00b48be2, 0x47547bfc, 0x66082a74, + 0x36e75724, 0xb9edfcf2, 0x587de764, 0x157f056e, 0xaaad77f7, 0x0eb70e2c, + 0x73f78eed, 0xddf12766, 0x051f3102, 0x28e3feaf, 0xbc476d78, 0xe871fda2, + 0x2768c9b9, 0x91929eb8, 0xc6ded933, 0x8e47e42b, 0x72789a6b, 0x075fbe2c, + 0xd7158076, 0xdcefbec7, 0x4ad4eb83, 0x909da199, 0xcb1694d7, 0x57d76a86, + 0xdef22fb4, 0xa3ae159e, 0x90d31df7, 0x6d5b4e9f, 0xfb2a99b1, 0xcfc11dee, + 0x5fc974fe, 0xec70b7f7, 0x818d68af, 0xdff057e0, 0xfd93630e, 0x41e21953, + 0xedef6f3e, 0x7a157ea3, 0x2116fd28, 0x81fe15be, 0x2c63577a, 0x7c795f82, + 0x99d535b1, 0x0fc00b63, 0xe3037ff3, 0x61d57f62, 0xdcbfcc76, 0xbccab8e8, + 0xc8aae93b, 0xafd399ad, 0x8a54f9f5, 0xea8eeadf, 0xe9e99369, 0x50535bca, + 0xfd61f2de, 0x5f3a7f46, 0xfe449df2, 0xe315b285, 0x4aebf9d5, 0xf2f1c3ee, + 0xf874984f, 0xadcf75bd, 0x3f2e09c3, 0x529e01fa, 0x7b75f102, 0xa6c52faa, + 0xfbac1fc2, 0x7ccacf24, 0x1c137054, 0xe4307fe0, 0xa054f6ff, 0xbfee4a9b, + 0xf50f7210, 0x63e2462d, 0x5fc470fb, 0x7e2d7ce7, 0xcdf8b5f3, 0x3e2318f7, + 0xcd273666, 0x9323e0a7, 0xfc17df0e, 0x28e9a7fa, 0xc7abad9f, 0x235abcd3, + 0x8e51c3ed, 0xffa0535a, 0x59e7dda1, 0xe7986bf0, 0x6799efd0, 0xabd11065, + 0xfa4679c7, 0x33df679e, 0xed58c8cf, 0xadeacf3c, 0x5c5fa8e1, 0xfb8664bb, + 0x8ec95cc3, 0xd97963b5, 0x768614b2, 0x05d0f589, 0xd5e912fa, 0xb8a068d6, + 0x30ef22a1, 0x83f20dde, 0x35a1f88e, 0x28f4fad7, 0x0b656f5a, 0x575bd9c6, + 0x51e7788f, 0x95aeb728, 0xb407682d, 0x81fc72e6, 0x0f50ebdc, 0xa638a6b4, + 0xc18f7951, 0x39fa14b2, 0x0fb7f953, 0x0c0bf225, 0x73f34656, 0xbe3b45ac, + 0xfd45e01d, 0xcd997805, 0xcd034aed, 0xa7cad57f, 0x7777e256, 0xfe964df5, + 0xa7eb40d6, 0x6b45cf16, 0x321c8d64, 0x73c695bd, 0x8ac93afd, 0x0cf050f3, + 0xc67d349a, 0x607c2eb0, 0x2eb0d679, 0xfd94b8bc, 0xeb3d626c, 0x9f885bd4, + 0xc05d7cbe, 0xafa8ea7d, 0xa77d3f70, 0x57affb3c, 0xdfc67a7e, 0xd04db89e, + 0x16ef5fd3, 0x7ca9cbab, 0x5cbaa15f, 0x4a37a7e2, 0xbac3befd, 0xfc502d3b, + 0x78e77774, 0x02796f1c, 0xaf5c4a6f, 0xd68949fd, 0xd5bd3cd5, 0xabc17e88, + 0x155c78e3, 0x8ff301fc, 0x683b0e49, 0xb67a793e, 0xef8994dc, 0x994f546d, + 0xdcb7f427, 0x8ef46b04, 0xa077ae60, 0xaaa364de, 0x0557e8ac, 0xfe44479e, + 0xc3fe7942, 0xad64f3fe, 0xb38aacff, 0x201b123f, 0xf7299ece, 0xc608ed7d, + 0x64c976db, 0xf30eba37, 0x7d7d8575, 0xf06de9e5, 0x1a4f7cbe, 0xe6555bed, + 0xf6c78fef, 0x7de12b86, 0x21db7de1, 0xcbc63063, 0x72a31af2, 0xf48a2fc9, + 0xaffbc405, 0xfe94fcc4, 0xe12df4da, 0x2df6d5d3, 0xa19f096b, 0x86bc8fe2, + 0x164fb42b, 0x5596e7f0, 0x534cfb7a, 0x79fa2e4c, 0xcc4a7ff9, 0x55f3c1d5, + 0x06b5cf41, 0x506b0beb, 0xc899764e, 0x3c3b6f6f, 0xdbed8747, 0xe789170e, + 0x9e7a7643, 0xe382933d, 0x7f38eb87, 0x14bde32b, 0x7ca5edcb, 0x7fe7a9dd, + 0x8dfefa84, 0xaa65d4b8, 0x2ebe69f8, 0x6dc4fc93, 0x845cdf06, 0x95f1ec1b, + 0xe943efb8, 0x2b58d5e7, 0xebb6d1c1, 0x0fa8f3fc, 0xce4dacce, 0xb6d23544, + 0xcc70c06b, 0x189db7fb, 0x3fe78e91, 0xb04c9eda, 0x66d81ea1, 0xfc443eb0, + 0x86cc2ab6, 0x87f4ae72, 0xac7e60e3, 0x1cc8d76d, 0x4edbb3f4, 0x4ca17870, + 0x73d4377e, 0xa50efee3, 0xf59d70df, 0x8c8fb857, 0x7940c9fd, 0xa4dfc5b4, + 0x1abfa1c5, 0x5f9c0c6e, 0xbb5dfb40, 0xc1296a7f, 0xf1e3ecad, 0x7d95efb7, + 0xd17efe3d, 0xf80bd07c, 0x2b7fdfde, 0x702b9562, 0x1fbf917f, 0xdc7e40c7, + 0xfa62beca, 0xbdf5a5ab, 0x2677cb64, 0x0fb13d4d, 0xbe031a88, 0x571e40f2, + 0xc3c65c53, 0xe52b5fe3, 0x5f42f980, 0x3ec7cf2c, 0xdcedf213, 0x4f5d1516, + 0x1e3e98eb, 0xc8da7af0, 0x7f99f1cc, 0xaf973fbf, 0xbacc57de, 0x73a777fb, + 0x00b9953d, 0x32d5e9d7, 0xa1fd47ed, 0x7b7f9dfe, 0xf3e88480, 0x4effb099, + 0x3e705cc3, 0x5ab3fb3d, 0x067c1578, 0xfe057d89, 0xfe22cdf5, 0x991bf03e, + 0x9bee51d9, 0xcfe41e0c, 0x3f9f8d90, 0x67f20f7d, 0x6a92c1a3, 0xed017ca5, + 0x64bb6573, 0xb75c7f4f, 0x2f84cf1a, 0xd76575c4, 0xd34e3a08, 0x92ecbfe9, + 0xd6dfee29, 0xf3162570, 0xe50fd003, 0x4f4d5d3b, 0x7b7f90d9, 0x4e312382, + 0xeffa61fe, 0xa1f8bf66, 0x6db67bc8, 0xfa8e973c, 0x6260f41d, 0xfa67ca1c, + 0xff9e46d7, 0x7da1c96c, 0x273f1bbf, 0x73ddbcbb, 0x7349ec95, 0x940f6ca3, + 0x671a1c57, 0x4df061fc, 0xf007c2d0, 0x1478450c, 0x3eadcb38, 0xbd737f3a, + 0x5d84ffbc, 0x1cf14b85, 0xd1f9e608, 0x94682fbe, 0x582add69, 0x40ac7b2f, + 0x7e030997, 0xed082fb1, 0x8a24a7d1, 0x6f924e0b, 0xd40e70fe, 0x4ca4f05f, + 0x1f1bbde5, 0x7480d0fa, 0xbca06f5d, 0x99a682e1, 0xfc57da46, 0x122cc494, + 0x37d9ab8d, 0x12972c50, 0x09f6dd5c, 0x680fedf8, 0x7d0b76cb, 0xe37ef7e0, + 0xa2fb198a, 0x9267a9f1, 0x017efbb5, 0xcb103bfc, 0xdfe047cf, 0x126bfe96, + 0x416d0e91, 0x5ca3358c, 0x5fc85bea, 0x3e7e5e61, 0xd9d76db3, 0xeb97a414, + 0x5e292f8d, 0xb01c93d9, 0xf33fbe46, 0xfc8938ce, 0x5cdf81d2, 0x5008e699, + 0x6fc8b67f, 0x13b8316f, 0xb7dd3ed1, 0xe38f2af1, 0xae71e2ec, 0xee67fb1e, + 0xf26f1e20, 0x2c1c5106, 0x0532d6ab, 0x3cec01e5, 0x36b93fcc, 0x09b198ad, + 0x0dbb41ca, 0xabab4456, 0x05c9287f, 0xaaa141ca, 0xb61e455f, 0xb2947c88, + 0xd8b661bf, 0x6feca397, 0xf83bf650, 0x77eca1c3, 0x3bf62d98, 0x78eb1dbc, + 0xc19e0e28, 0xd9385f3a, 0x5ffb7eb1, 0xe2cfda7a, 0x3fd1efbf, 0x4f9fee6e, + 0xcbecad5b, 0x47146088, 0x8dfac237, 0xcd86c395, 0xabf51778, 0xfe4c98e1, + 0xef23ded0, 0xf1f5aac5, 0x38737d0a, 0xd72f31c6, 0xd1fe4419, 0xc316f947, + 0xa98dcf91, 0x862597a4, 0xca0bae76, 0xb375def8, 0x338eaede, 0xe7c71d3f, + 0x9d2e22bb, 0xfb7ab7af, 0xb7afcc21, 0x688cf259, 0x148e1b8f, 0x367e464c, + 0xf919e7c4, 0x54e6b9f8, 0x9e844ba4, 0xa3457ff8, 0x05b36e32, 0x7bf257fb, + 0x2cc71161, 0x598577c8, 0xbf3fbeb3, 0x4a83f227, 0xdf33af7e, 0x7be33f17, + 0xe33b7bf3, 0x8bf71d38, 0xff71bbe7, 0x3b7bf2cf, 0x5265fe91, 0x30f1a4cb, + 0x8ef88ac4, 0x6ebdf9c0, 0xfcb1bcf3, 0x567147de, 0x9ceb7f9e, 0xbdf90f6f, + 0x58dffd6e, 0xff7baf7e, 0xbaf7e43d, 0xf9837ff5, 0x797ecebd, 0x50f96f7e, + 0x5b3fed1d, 0xe3c4dc7e, 0xffbe66e4, 0x65e424c3, 0x668277b9, 0x74f284ff, + 0x184909b3, 0x275e5f27, 0xbcfe464f, 0xa0b3c96c, 0x78221a7c, 0xb064c83c, + 0xd43f464f, 0x85191114, 0x711ff97c, 0xabaf3469, 0x3f888b11, 0xc87982af, + 0x722d89cf, 0xef797960, 0xca649902, 0xd6177f2f, 0xd57cf324, 0x7758b368, + 0x87e4b7df, 0xf3fbfe52, 0x3d1e5538, 0xed00fb2c, 0xce0d648b, 0x8fbf283e, + 0x127f405b, 0x7c50b79f, 0x7f3928c6, 0x76217187, 0xbb639f82, 0x601ce41a, + 0x3ea5c951, 0x2eec28de, 0x33ea126f, 0xa7a2ab37, 0xe10ae1ab, 0x2a478959, + 0x47cc5ddf, 0xa5794778, 0x7a09b8c3, 0x706f7d2b, 0xb573a00e, 0xbb4e8e02, + 0x6ea18fe0, 0x6a69a73c, 0x8ff286fa, 0x34df7aed, 0x36d4eb8c, 0xfc6a21ca, + 0xb973c526, 0x9cfe4dc8, 0xd8e556f2, 0x57e617ae, 0x7ca0064b, 0xc37c9b96, + 0x7b7dee11, 0xf51c36fe, 0x92a6d5ca, 0x0b7ef83e, 0xdc75a7d4, 0xe7572be8, + 0xaaf3fd5d, 0xf381f1d1, 0x969a5bad, 0xdb1c2225, 0xf6005e30, 0x3fc3f955, + 0x663a73a7, 0xea0dff66, 0x837a060f, 0x99868afc, 0x93b438f2, 0x01db003e, + 0xf8bb59ca, 0xcc959bfa, 0x2d37983c, 0x0e60fa6f, 0xdb3cabd2, 0x32974168, + 0x6de78338, 0x16cdb383, 0x45a6ff5c, 0xe2303e71, 0xed869b3a, 0xdd214627, + 0x3031c41e, 0x7b73b9cf, 0xb7f01bbd, 0x854f0ff0, 0x27dfc033, 0xafda4afa, + 0xb1f9ba51, 0x2f3c3b70, 0xc714dde8, 0x0723c4fc, 0x1794ffdc, 0xf6b7f8af, + 0xfe754950, 0x3fdfd3e0, 0x6ef88d31, 0x7982c1b3, 0x1316d77f, 0xaf2b9f9d, + 0x33f3a62b, 0xcbc53e50, 0xfe867f8f, 0xbb41ab95, 0xe97c2f4e, 0xad2b58a9, + 0xb124ee0b, 0x941f11ee, 0x849d9cd7, 0xc1f857f8, 0x8f8e1dbf, 0xb55de5fb, + 0xaf633cf2, 0x7b15dfee, 0x5dff5943, 0xfb884f75, 0x3fc85a01, 0x845faff0, + 0xb19a3232, 0xfddaf199, 0x983e0ad1, 0xa3f48627, 0xf0c373bc, 0x54be5053, + 0x92e16ff3, 0xbf8a4f0a, 0xff9b51d3, 0x3dac37bb, 0xb06defaf, 0x7574b02e, + 0xb3b50f3b, 0x177e0836, 0xf06a5f7c, 0x955ca386, 0xdcd8346e, 0xfb74baf0, + 0x973e2f0b, 0xc3667245, 0xfb64ac75, 0x818e1f5b, 0x430ec972, 0x8d3e54f4, + 0xde754950, 0x61ff05cd, 0xc3a1405e, 0x32ded7c2, 0xf7f1875a, 0xa2ec88bf, + 0xbd8ec947, 0xfc5e7446, 0x76be31f1, 0xbbf291af, 0x3da974fe, 0xef2b7245, + 0xbbec86fc, 0x2c48f64f, 0x3e00352e, 0xee15be37, 0x3a227814, 0xd2753a0a, + 0x92beafcd, 0xe4e8577f, 0xde3b3dff, 0xfd85f242, 0x3f023ca1, 0xc606f2bf, + 0xd9323ffb, 0xaf45fe70, 0xf38e103c, 0xc45faf38, 0x63c37af9, 0xb71876b1, + 0xb58ee0c8, 0x2fbf93d0, 0xc467fe7a, 0xfe8e0b6f, 0xcc7fdb8c, 0xfca3a09e, + 0x7bf29ba5, 0xd0efeb85, 0x0da2ffe8, 0x85ffae3c, 0x11de4d9e, 0x0b8e2e40, + 0x937e72bd, 0xe7d9f289, 0xf6860f31, 0xdf327bcb, 0xa7eec7b7, 0xdf629078, + 0xe54d2780, 0xfe1e842f, 0x894ebc43, 0xfc359b7f, 0x3378f35a, 0x64d3e7d2, + 0x25ea1c7b, 0x05bbd317, 0xa0efa43e, 0xc4e8f95f, 0x1e1f4e38, 0x6076a33f, + 0xf7c78e8f, 0x40d9bf58, 0x3b5550f1, 0x8f966e71, 0x1f18a0ff, 0x7cc60ee0, + 0x5658f9ca, 0xd44fc814, 0xe7c67427, 0x29e7359b, 0xcb9be4bb, 0x2e2acd7b, + 0x7bbc8adf, 0xefc64fa6, 0xf2e31f9f, 0x3292ed83, 0x1c6f2e09, 0x4b3bdf7d, + 0x27cfce1a, 0x75c9037b, 0xb5c8418d, 0x27c2bbf6, 0xee9eb700, 0x05f85021, + 0xfc248ffb, 0xbad2d517, 0x1dd8d26d, 0xbc2f1c2e, 0xdc8a7f7b, 0xfff2102e, + 0x7f38bc7e, 0xad9fe425, 0xf3a1b98f, 0xcf06a545, 0xbca1cf8b, 0xbef7e09e, + 0x90376e94, 0xdb717e5d, 0x06ef0ffe, 0xab58b939, 0x7f56a9c8, 0xd169cbfa, + 0x7f116fab, 0xc5e9cbfa, 0x0362b7da, 0xb78ee9ca, 0x2eee0ec8, 0xfab9ffa7, + 0xdfdfc153, 0xe8a7f0fc, 0xe8f09ec3, 0xe3ab0faf, 0x21f501ad, 0x9f531dfc, + 0xa5f0537b, 0x6fc29df0, 0xeb2e5f0b, 0x93a77a83, 0xebbe152f, 0xef854be4, + 0xd73bedba, 0xfbffcfe0, 0xe00df85b, 0x60faec72, 0xb3d01252, 0xc9fb91b4, + 0x9620eed0, 0x5a764f01, 0x41e558c6, 0x55db6f3c, 0x6b95f8f6, 0xfddbeafd, + 0xfabf0eca, 0x22f2bf4e, 0x821efabf, 0x3f61b4ab, 0xbcc96fdf, 0xa586fa9a, + 0xdd161dcc, 0xf31e0e75, 0xcfd02b58, 0xf4f3c6df, 0xb8f0258f, 0xb8c62fa9, + 0x891ff682, 0xe13e2a7d, 0xb43bb467, 0x354e54fb, 0x5b7fa4ca, 0xf8f3813c, + 0x3c9209e0, 0x3fb0f4b4, 0x4d3b895e, 0x1e534394, 0x2a3a3806, 0x60a0fc79, + 0x94e19dc9, 0xbb4c69cf, 0x850ae31d, 0x2c31f987, 0x73143f65, 0xaa09f5db, + 0x98170efd, 0x319be9fb, 0x4258d64f, 0x35828bf1, 0x0fcd7a5a, 0x0be2907d, + 0xf7b4abf3, 0xad7c2900, 0xd68b0bc4, 0xc42fbf6b, 0x1ee8847b, 0x47da4a85, + 0xfb46b0b4, 0x0e7c89dd, 0x41273c7c, 0x2c1909d8, 0xf9bde443, 0x57a11239, + 0x6f43ca27, 0x21cbfca7, 0x1da5f299, 0xbde1328d, 0xfb449b63, 0x863b9869, + 0xf99ca5e4, 0xf8299f48, 0x60f284b9, 0x5cdf59ec, 0x73dffd7a, 0xa52a851e, + 0xff0f1ff5, 0xd52f3c2d, 0x8ddf489f, 0x4e7f9de5, 0xaf7598f9, 0x104f7e3f, + 0xdf6a1fed, 0x35f74613, 0x9dbd37b5, 0x85e528f2, 0x07ba364c, 0x9497cf61, + 0x6a5f6b7f, 0xd57d422a, 0xcafdcc9e, 0x0e5f4d65, 0x39657ae7, 0xc098df3f, + 0x34744dcf, 0x94f28dfe, 0xca268d1d, 0x84f6b933, 0x7ae11f90, 0x9cfc8823, + 0x292fa6f6, 0x9acffcbe, 0x3788b94f, 0x3cf187b7, 0xbfb8bb4f, 0xf47bb5c4, + 0x2d87980b, 0x446bdbab, 0x9bfc65bf, 0xdf5d90df, 0x67b72afe, 0x1eded0da, + 0x5bae7883, 0x7dc44e33, 0x4d0ecca8, 0x0db77b45, 0xb1912385, 0x9d5dcfa1, + 0x081a1eea, 0x5e50df4f, 0xf3f146f5, 0xfc18ffd2, 0xb9dfb448, 0x63cc31b4, + 0x5fde7096, 0xf518fc9d, 0xd79e1ec1, 0xb17be657, 0x1fd90976, 0xc1f79bd7, + 0xfddfee04, 0xe4b799ef, 0x9f7991bd, 0xef4e6ffd, 0x98d43c62, 0xba2e5ddd, + 0xcf1379f3, 0xb30f6d17, 0xc837bc11, 0xffc486ef, 0x157f7465, 0xfd7e1ee8, + 0x6ffbf779, 0xe99eef3e, 0xa0ae787e, 0xf3e305bb, 0x21bf37ae, 0x3d5efef8, + 0xe87fe137, 0xfd3b15fc, 0x6fd7c67d, 0x91c3a257, 0xee9efb88, 0x5f02bc38, + 0x274e74b9, 0xcd12c3c5, 0x4d9fee74, 0x8e87e28d, 0x33618ef5, 0x57877586, + 0x25fe1bf1, 0x31273ed1, 0x07feaba6, 0xa619efb3, 0x7d57779e, 0x58d1be3e, + 0x379d3f7b, 0xfca50b29, 0xc18f6e2c, 0x36cc2f76, 0xf713fe71, 0x990f1c3c, + 0xa606307b, 0x738347f2, 0xe739c23e, 0xc0ac9fce, 0xca2fb4b2, 0x35e718ba, + 0xdc4725af, 0xc710b08b, 0xfb3b352f, 0x72f9aa60, 0x2f4073b2, 0x511c47b4, + 0x1ccb9e3c, 0xe1011cc3, 0x37ce6b77, 0x994bf62a, 0xea3aa1b0, 0xbe517ad2, + 0x645ed5e4, 0xb8e9b57f, 0xe026d87f, 0xb767e0bd, 0x1a8e7917, 0x5c58ff31, + 0xcea8d473, 0x7389963f, 0x3fe3fea9, 0x23f3c891, 0x87f6be9f, 0x8bf748ab, + 0xa3a7d45f, 0x5d2256bd, 0xdd5d79a2, 0x98ae747a, 0xff9c0adf, 0x14be1d43, + 0xb4abcc23, 0xc791af76, 0xf4fcc523, 0x9beff4be, 0x79ae9b5f, 0xaabb9d12, + 0x8e7ce897, 0xeeacaed2, 0x93b424e8, 0xe8226a8b, 0xa7dc473e, 0xca9dcfc2, + 0x7860fb7e, 0x8eb2493f, 0x4bf7dbf8, 0xd21bf689, 0xe9dfb41f, 0xbee0f08e, + 0xcaee936a, 0x676899b1, 0x8ce7e30f, 0x438307d6, 0xbbc77e0f, 0xc41b5f02, + 0xbf780779, 0x07c7df12, 0x4ff1f6f3, 0xfedf68eb, 0x9409b90b, 0x7bdd543f, + 0x72075291, 0x36b26494, 0x49b8c0b4, 0x0f28bd15, 0xb9d13dbc, 0x5f71f105, + 0x18e52e94, 0x421ce1c1, 0x8e6f80e7, 0x753f21ba, 0xf818b306, 0x9e7e527e, + 0x4f85867d, 0xb5d850a5, 0xee9d9933, 0x3983b8e1, 0x6d7bdea9, 0xd7da3b46, + 0x336e61ef, 0xa3f7ee93, 0x0f3177f7, 0x5e61ef3d, 0xac2fffaa, 0x5f0aca85, + 0x17de3f02, 0x3cf1f9cd, 0x8e8160a6, 0x47dc226f, 0x3f278643, 0xfe9ef80c, + 0x94fe80cc, 0x76e2ad2f, 0x9ee0f5f0, 0x574bfc2e, 0xf210f3a2, 0x2fe4c77b, + 0x7e82af9e, 0xf12f6674, 0x91ee7283, 0x7c11884d, 0xdb72fdf1, 0x0f99d1dc, + 0xe2bf450d, 0x5bd24156, 0x509fdced, 0x2edc0dce, 0xd9ef01e4, 0x343a0489, + 0xa7bdf95b, 0x3dbd2acc, 0xc793ca02, 0xe59fb4c9, 0x20d6e08f, 0x4331fc7f, + 0xd9a5f716, 0xd134fda9, 0x3371d4ef, 0x7a82f797, 0xc96ebe93, 0x9327f3c2, + 0x8afd6b7b, 0x5c6f449f, 0x29cf011e, 0x7fefb4fd, 0x88f59aca, 0xb543a9d7, + 0x2cb4cdfe, 0x38bdbd6d, 0x2a962466, 0x4b845ee9, 0x193fc289, 0xfdab06cc, + 0x1d3e6513, 0xd118af53, 0xe493ec17, 0x597482bc, 0xb9d9db7c, 0xcf4ede74, + 0x4d111ede, 0xbcd1cff7, 0xe6f02b5a, 0x55cec646, 0xa179e998, 0x20ecc2c2, + 0xc4569ff7, 0x8552f3d3, 0x55b7de95, 0xf8e7a40c, 0x90dfc724, 0x9f95053e, + 0x670fd1e9, 0xee34e955, 0x9acf8203, 0x9d1d5e75, 0xd124d85f, 0x82079a7e, + 0x8ef1739a, 0xa73607ac, 0x61739c52, 0x0c41ed43, 0x1d78141f, 0xf39c9093, + 0x883a2d0f, 0xc06bb2cf, 0x158023e9, 0x24a61c12, 0xa763eb94, 0x7ac6df67, + 0xe37b1be6, 0xd05183a9, 0x1b0af9ff, 0xc549f5c1, 0xac5e7a28, 0xb3dc13b0, + 0xa4961c92, 0x67d2a46c, 0x6db73fc4, 0x824fa53b, 0x12ad13fa, 0xb63f2bad, + 0xe4078f33, 0xd7c0daab, 0xb304ea85, 0xdc74e50d, 0x1e1b19b0, 0x9df7a864, + 0x1dc70889, 0xe2278a53, 0xcd46d338, 0xeeb47ba3, 0x7bf19afc, 0x58dc2695, + 0xe9f988dc, 0x247bcbdd, 0x3acbcbe2, 0xff18edeb, 0xa649ff75, 0xde0740fc, + 0xe3fe80d3, 0xe32f7e71, 0xe2d3d7e2, 0x362f3f50, 0x5fd0e358, 0x79f62ddf, + 0xe97a045c, 0xc5eceb55, 0x9cce7fed, 0x25bfd2a7, 0xfabaecaf, 0xf2fbf411, + 0xea1b48c9, 0xe2918bbd, 0x28b6467e, 0x9b48f504, 0x19623bc8, 0xd65015ef, + 0x5833d45d, 0xebcc18be, 0x9492bce7, 0xe382728b, 0x7a5d8d59, 0x6795fd28, + 0xed6a3efa, 0x6d4b6f1a, 0x41cf47e1, 0xe747b2f9, 0x723ac036, 0x61b6d599, + 0x135dd6dc, 0x066dfb4a, 0x87e0fa4a, 0x7c3d6f89, 0xd56488bf, 0xeb6c3c63, + 0xd1121b2b, 0x392dd80e, 0xfa823ee6, 0xffaf037b, 0xe48fd3d2, 0x53e7c2ed, + 0x823eaf65, 0xa08a4f78, 0x2b9ff376, 0x36fc8c1e, 0x5d5efd6c, 0xa9bfbc22, + 0x7c52d4e6, 0xc2a240ce, 0x926d8cf7, 0x8cdd778c, 0x865d4ba8, 0x1fb898af, + 0xfbc0b06e, 0xed9ff5d0, 0xf4107703, 0x08e2ed6b, 0x525757ca, 0x671bd7bb, + 0xc10f7fbe, 0x7bc04ee1, 0x8cf3dd35, 0xb8f03edc, 0x5c9f2237, 0x51b40e76, + 0x7ee1cd7e, 0xd973e916, 0xf5c36b19, 0x0ee75ea0, 0x4ff5831f, 0x76087bf2, + 0xc70d1cd6, 0xeabd11fd, 0xed082c0c, 0xad1f0c95, 0x56c9654b, 0x259659bc, + 0x64eb7f3f, 0xd7927946, 0xa53f5237, 0x99e61b66, 0x42bf5e8b, 0x13f61cf1, + 0xfc8feb66, 0x4fcbc751, 0xfd13b04c, 0xc17e368a, 0x2a0ecdcb, 0x2a77643b, + 0x0f945fdd, 0xfbf40c76, 0x5877588c, 0x47d270cb, 0x2ed672c4, 0x9f013f7c, + 0x3abdf02d, 0xfb809dd5, 0x0af594c3, 0x219f99d6, 0x839ba37f, 0xef739bed, + 0xf775a149, 0xa519d706, 0xfc8c679f, 0x46f5bd7e, 0xb66e1ebe, 0xf42778f0, + 0x4fe514bf, 0x64931759, 0xae1d5869, 0x6c98cf73, 0x3e37accb, 0xfee2ddce, + 0x2af813ae, 0x430d6c41, 0xf8ffba42, 0xe9ffc636, 0xfbf23dfe, 0x15675799, + 0xf941ecf7, 0x4fc3a4e9, 0xe619bf2e, 0xe003f82d, 0x83013820, 0xf2a7f50c, + 0xe38b2c3e, 0xb669d233, 0x2e2b7e61, 0x33dd116a, 0xd307f0a1, 0xdda0477b, + 0x995bfab0, 0xffb94bce, 0x7f714a1a, 0x4ddf787f, 0x7af471e2, 0x639e07c0, + 0x7bf07772, 0x5ac31a9f, 0xf403fe5e, 0x9bdc58df, 0x0dbbc6e2, 0xf756fefc, + 0xdc5df174, 0x5778dd27, 0xa27dc92c, 0x7601eb89, 0xd38d304f, 0x7e6cf068, + 0x8f4fbf1a, 0x85c7f6a7, 0xde671d9c, 0x955f707b, 0x7ba467db, 0x1822ab39, + 0xb55367dd, 0xfdc50064, 0xe07dbfea, 0xbda186df, 0x639f84b2, 0xacf0caab, + 0x55ff7dc4, 0x70e34cbf, 0x1724de48, 0x260e2fb6, 0xdd355d3d, 0x4071809e, + 0xba10b4e7, 0xfba7ba57, 0x28323f5e, 0x09ec89e7, 0x0ae78f88, 0xfdf533fa, + 0xca4e7f41, 0x57748c3d, 0x3a73d1f2, 0x8ecc22f3, 0x21de5bf7, 0x6e15770a, + 0xbb7e420e, 0x14e828a3, 0x178f6bc6, 0xb8c30d2d, 0x7e4e1de3, 0x359b273f, + 0x8f3eaed1, 0xfb24e7f9, 0x5657e461, 0xdeedd8a0, 0x1ed3c47c, 0xbdce999f, + 0xa847f901, 0x7f8544ed, 0xbe77aafe, 0x8ddaed87, 0x92e35ee2, 0xb6cda6af, + 0x6bf1faaa, 0xf27edfe7, 0x37bf330c, 0x7644cea9, 0x8ec27dc1, 0xb3bc9972, + 0xad5a0ed1, 0xf607fe73, 0xe9f85aef, 0xa277b470, 0x17fbf067, 0x09be31db, + 0x7a0a4f75, 0xff7c649d, 0x98517ba0, 0xb2f11bc8, 0x0f28d1f3, 0x9ec7a7bf, + 0x07e58850, 0x1f70d886, 0x99e45390, 0x7c44b958, 0xf9c2d272, 0x146364e4, + 0xe33e8fdf, 0x30e9d3da, 0xab8e938f, 0x7a848f6f, 0x79f81b27, 0xcc3cbf8e, + 0x2f9619cf, 0x60d2913b, 0x7baf3eed, 0xd97bf297, 0x0bf85def, 0x93da6f3a, + 0xaa5bddfc, 0xd21987dd, 0xce15fedb, 0xb5c67a33, 0x1287a849, 0x2d9f4a4b, + 0xdbdabd44, 0x2fbe2df9, 0x2394b637, 0xff77ca3e, 0x7fda0a7b, 0xda5ebbed, + 0xaf9e1071, 0xdeba9d19, 0xade97df8, 0x67618fa9, 0xd72f9ec2, 0xae403d03, + 0x34edea9f, 0x717e06f6, 0x63a6f04d, 0xe6864bbb, 0xf6378849, 0x1bb31b8b, + 0x5cdc6d3f, 0x115fa12f, 0x4f4e58dc, 0xe11c33d9, 0xc37928b8, 0xa71e1ef1, + 0xc97e8fd8, 0x188f0de2, 0x72c7f78a, 0x1f3ff5fe, 0x8ac5a048, 0xaed0327d, + 0xe71656a4, 0x27143c97, 0x025faff6, 0x0ddea9ef, 0xcbce57be, 0xac344495, + 0x66f44b1d, 0xee166f5e, 0xf74feceb, 0xfd7e5d32, 0x5fb574a5, 0x0eecffe5, + 0x9d3f9f2f, 0xa9bcc6e7, 0x7bf7df87, 0xe4068a09, 0x71266db3, 0x51f38f8e, + 0xc104d6db, 0xda8f9c67, 0xa8f00eb6, 0x9cf3b6e5, 0x8736ada0, 0x6bdbedf6, + 0x501ed073, 0x6b999fe4, 0x36677ee9, 0xda3876b0, 0xc23d8add, 0xf4e9b51c, + 0x8e9b53de, 0x3c75ebf5, 0xbb8ca73f, 0x7e24e5f0, 0xeb9998df, 0x0f2f85c5, + 0x94c6fba1, 0xcf37af7e, 0x4d46d501, 0x5b479079, 0xef9bd69e, 0xeffdf85b, + 0xcbf1f73b, 0x93c61ec2, 0x40f79d85, 0xbd73de76, 0xf2f05255, 0xfa0e5260, + 0xaaf28ca3, 0x0be07bbb, 0xbd21ae05, 0xf30b3fb9, 0xbbceb863, 0xbbfae23f, + 0xf331c33e, 0x6fd72836, 0xb6fb2348, 0xe9f8e74d, 0x79e71c30, 0x3ebaafbe, + 0x9cf947c2, 0xfdb967fa, 0x5de62e5b, 0x424ce11f, 0xc2a17a7d, 0xffee2f16, + 0xe96c3b26, 0x98e11589, 0x61dfaff7, 0xd5f8c0c8, 0x63fb3527, 0xad3e2f91, + 0x37ee9878, 0x75e3bc1c, 0x6e94a3ca, 0x1c7de07d, 0x8336d2f7, 0xd2acdd0d, + 0x8b5c5ebb, 0x56e948f6, 0x5be716b9, 0xe53f75ba, 0xbed52fc7, 0x71fb8e15, + 0x9144d42f, 0x53f08c1f, 0x1cf7fafe, 0x2ff8fe0f, 0xabc464f6, 0xc91591f7, + 0x7f78b5ee, 0x5a2d90c9, 0x3c7d17bc, 0xedea10e9, 0x18cff50b, 0x1fbc56f5, + 0xa6fdfb56, 0xeff96d06, 0xe4abaf3d, 0xd4e39091, 0xdcc85c74, 0xdda9f507, + 0xb5645feb, 0x3f18edb3, 0x9727bce8, 0xdae8edcb, 0xbb379475, 0x6e6e78fe, + 0xe9da853c, 0xa379ab9e, 0xe231b7f8, 0xe6b65efe, 0xdbc424e8, 0x5a2427bc, + 0x36bde6ef, 0xcfea00e0, 0x9aee3b53, 0x93d9cf42, 0xe8f91f09, 0xd67ee085, + 0x061bc946, 0x8e28cb65, 0x9e6ac2ef, 0xee5bca17, 0x8d69ee77, 0x2af8fedf, + 0x0d05f7ed, 0xbcc2bf7b, 0x79f99176, 0x3f741f8a, 0xfba1e3c7, 0x605e177f, + 0xac2dcfe4, 0x2814cef9, 0xcca851be, 0xda63fdc3, 0x264dc01f, 0xfff0fff0, + 0x4daee346, 0xe1ea3d47, 0x651b5531, 0x731957c4, 0x2349643e, 0x021bc5bf, + 0x8137cfe3, 0xeb4992dd, 0x4ae7cd21, 0x8f3a2f75, 0x5059ef0e, 0xda03de26, + 0xe4eb839c, 0x1b30ba95, 0x9cd69fdf, 0x02d57683, 0x21f9d328, 0x0bce2956, + 0xf1fee87b, 0xcd06d505, 0x1ec5e07d, 0x7255996d, 0xef14b0fb, 0xfa470ed3, + 0x92bb50b7, 0xa57ada2d, 0x91e39f30, 0xfb51ffb8, 0x5b7cc5de, 0x2b7da45f, + 0xefd498df, 0xb1547b15, 0x0e38958f, 0xe460b228, 0x7237bb97, 0x04b77a3d, + 0x0c3b45f3, 0xafb234ed, 0x420e3b3c, 0x2878aab9, 0xdff54fd9, 0xca5bfdf2, + 0x0caad4f9, 0x279e3a7b, 0x88375aab, 0xb25bbfe6, 0x7a863ea7, 0xd859ba60, + 0xe1ee8c57, 0xa44e2aaf, 0x1c23fbf5, 0x2ced0132, 0xf729ef6e, 0xeea227f5, + 0x18e371c2, 0xb53f8fbf, 0xb37a8bd6, 0x3fae29ea, 0x81563b14, 0x4f675f3b, + 0xb36e75c1, 0xcdebe9d9, 0x23a56ff7, 0x09bff9dc, 0x4557bc22, 0xfce8c2f8, + 0x0dd4517f, 0xc59ba7ad, 0xabcca0fa, 0x7dd07255, 0x293d4ae8, 0x9cdbeb99, + 0xa28bfb5c, 0x0b39c51e, 0x6fab1d72, 0x3c147c01, 0x1fa2b3ad, 0xbb6789dd, + 0x13ef1d3d, 0x94175d68, 0xcc9cf089, 0x47367ae0, 0xf6061bdc, 0x3c137dbb, + 0x9a759383, 0x32706578, 0xc163a7b7, 0x5af1c27f, 0x5438f227, 0xfc839658, + 0xe6a9c079, 0x19e53c1e, 0x302be02b, 0xa3f4fe3a, 0xd274f000, 0x7bc7027b, + 0xad12fdeb, 0xa21f3047, 0x83afce5f, 0x2ad00e28, 0x4e8503d6, 0xb4d92fc0, + 0x54bd09ce, 0x21f80ab5, 0x2da1ed15, 0x6afa835b, 0x0be286f8, 0x3ebe2eec, + 0x7c704554, 0x4c393d56, 0x6f82e5d8, 0xbf120c9e, 0x6cedc0c7, 0xec51fd65, + 0x3d3e6570, 0xef40e1d9, 0x7c2ac961, 0xe999d3f9, 0x7dead93d, 0x5e74fe94, + 0xd2986e60, 0x0bc1550a, 0x5c067825, 0x6b7d91d2, 0xde0892ce, 0x2a7ad581, + 0xb259d51f, 0x8da6ee51, 0x11f179dd, 0x7e7857d4, 0xebf47907, 0x39bbbeef, + 0xa951f707, 0x7dc472fe, 0xeb0fc8ca, 0xef183799, 0xd894afd9, 0xa03acd69, + 0x8fdfe32d, 0xb9fabb63, 0xf89efd5e, 0xdcfd9ff7, 0x69d8c159, 0xf85d8590, + 0xebc347ec, 0x4665fbd5, 0xb93c7236, 0x5f4f308e, 0x597677d2, 0x0467ef8d, + 0xcbfcee1f, 0x6e3023ab, 0x687dae31, 0xe9679e2f, 0xd3ef53a7, 0x5ed660ed, + 0xa3b4efb8, 0xee17ad31, 0x2438eb4b, 0xf0033987, 0x038056f5, 0x572ff1e3, + 0x5ed9e998, 0xf0652ac3, 0x8f99da2b, 0x6bba67f6, 0x5f902ccc, 0x73b934ba, + 0x739319ff, 0x3ba5f7d4, 0xa4ec7d68, 0x9fa9a5d3, 0xc77787e8, 0x569dfe3f, + 0x87f913d6, 0xebf715e3, 0x06b75e20, 0x740a4cb5, 0xe04aafde, 0xafbeda6d, + 0xe0e33f68, 0x943a8dc6, 0x3a35c1f7, 0x26b93acd, 0xca43ec59, 0xd7089964, + 0x61417db4, 0x438f4859, 0xe6082db2, 0xccfc6ae7, 0xd7e00ce8, 0xfb11e3f9, + 0x8702fdc7, 0xa7842d93, 0xf25a86dd, 0x365f772b, 0xbb29fdd3, 0x8125958c, + 0x23eccce0, 0xd8ebc405, 0x5f6833f3, 0x5e157fca, 0x7a87b5c7, 0x588e3173, + 0xbb1c78c3, 0x7d71bf1b, 0xd185b1d4, 0x710ef739, 0x1b63a80e, 0xa01ebca3, + 0x77dc49e2, 0x8b7df203, 0x80d63f7a, 0xe32f1d86, 0x28de5efa, 0x72e4fed1, + 0xf7118b7d, 0x221aba5b, 0x65bfcc64, 0xae3dc558, 0x59b0cb7a, 0x9c38392a, + 0x17e7e7ac, 0x07beecc6, 0xc972bdc7, 0xec87e748, 0xef747c07, 0x11c695c0, + 0x3cefbebd, 0x6c156bce, 0x7b3bde0a, 0x5f119938, 0xd0c1f3f8, 0xf29ac16d, + 0x8899d958, 0xd4cd34f2, 0x002da0f2, 0xc4528add, 0x7aa370fa, 0x89fff3cc, + 0xe8a63b1e, 0x8eaca731, 0x74a46487, 0x817163d3, 0xc962d8f4, 0x5ef8871a, + 0x871694dc, 0xd87c5cf4, 0x8f481310, 0xac38076d, 0x007f7720, 0x7b67c3f9, + 0x9bb1e81d, 0x0eac7a54, 0xbf0058f4, 0x3ae52924, 0x5ff3cc7a, 0x51db6f23, + 0xe798058f, 0x1fae14f0, 0xbc363d14, 0xb1e914f1, 0xcd3a75e1, 0x29feda39, + 0x5263d3d7, 0x2c68accc, 0x01216c1b, 0x89f106f8, 0x27c47779, 0xd41c713e, + 0x9629f967, 0xfd9f4bbf, 0xecfa7af8, 0x8abf08bf, 0x3afc5b3e, 0x3ba37f23, + 0xdfe231df, 0xfd18bbc5, 0x26e2cfce, 0x3716cfae, 0xcf0fbe31, 0xec0d8f4f, + 0xff18c7a6, 0x6f2f165d, 0x7d486aef, 0x2fe85ee6, 0x99b06ed3, 0x97667ea1, + 0xeb56cb5e, 0x1e94fcb5, 0x1ba1daf4, 0x0baf6bd3, 0xaafa06bd, 0x7f51ea2f, + 0x6a35b0be, 0xf763977f, 0x5edbf3e8, 0x5b78f943, 0x4701f3a6, 0x9dfebe45, + 0x90b3e7d1, 0x1e11eaaf, 0x4235d390, 0xdc2adb5e, 0x03f8ffd4, 0xdb657e7c, + 0xca0f5a24, 0x57bdb8eb, 0xf07b235e, 0x31a4e180, 0xff3ed15f, 0xe18926e2, + 0xa6e9b2d1, 0xfef1a7ca, 0x8192f630, 0xd4e53889, 0x143f150c, 0xf8a12a8c, + 0x999e8161, 0xc96ddf71, 0xb73fbe28, 0x7b959444, 0xf53b0ba2, 0xcdbedfa0, + 0xf7e9fb86, 0x7bcffc34, 0xdcf7134e, 0xf2417b4d, 0xdd5ffde0, 0x712a7bcf, + 0x97fbed38, 0xcba77cc5, 0xf61f842d, 0xde73e06e, 0xe5e3fb2f, 0x8d4bc090, + 0x478bc5ac, 0xe517880a, 0x8782ad5c, 0x565bb7e2, 0xf8a75c60, 0x32fc8959, + 0x782b79ff, 0x761f76ea, 0x909dff23, 0xdb62f7ee, 0xd25bbf35, 0x144477ed, + 0x7fcdfb3c, 0x323fa2bb, 0x37bc08d8, 0xf482f81b, 0xfc4ffb87, 0xb8c7421e, + 0x3d6a71fe, 0xc3c09afc, 0xe371ca88, 0x2e99add1, 0xd5f98afc, 0x804c1ff7, + 0xb71f67f9, 0x6303fdd2, 0x9ee898c7, 0x3e41adbe, 0x9f0a6fd2, 0x3e70fa19, + 0xecfd116b, 0x4b945c4e, 0x241a74fb, 0x2e13da0b, 0x37bf106f, 0x082df805, + 0xf67fecaa, 0x478124ea, 0x689efd0b, 0x006f5883, 0x4e57e8ef, 0xc01fd652, + 0x88cfca3b, 0xd7074e46, 0x2c874e16, 0xe567e3c6, 0xf30d92d5, 0xf70de5ea, + 0x8a3e711b, 0x50bf85de, 0xfc545d35, 0x27f357a9, 0x7bad547d, 0x34fbe225, + 0x1887e553, 0xfc06993f, 0x0cd891be, 0xfc3df7fe, 0x5f77eddb, 0x2f7bf3ae, + 0xa78e1f72, 0xf44788ed, 0xdc7d12f3, 0xbac2f26e, 0xddf5d610, 0xf06b77a5, + 0x6bb9fe38, 0x249abf9c, 0x3b01c62b, 0xefc354f1, 0xf056cf6d, 0x788afc84, + 0x63279c6f, 0xf8837e79, 0xf9bf1fdd, 0xb5083ee2, 0x9d37171c, 0x906ffde2, + 0xbcc02c6c, 0x7fdfe47b, 0x927b6f90, 0x2d1f435f, 0xe413beff, 0x2efb823b, + 0x77e24ddc, 0x34231a19, 0x7dfec279, 0x35b01db8, 0xfd1cf808, 0x1b06c3e8, + 0x2fe0a7de, 0x3d62b1ef, 0xaadf7b43, 0x420f97ca, 0xb12e3180, 0x28ceccc5, + 0x76e5f470, 0x6edf5aa5, 0xb331620f, 0xbfee7ab2, 0x4f5ba09f, 0x1e528df6, + 0x5ea1e386, 0x54f1806c, 0x7d7f2cf9, 0xd7e5f8af, 0x0fc6579b, 0xce32979c, + 0xd87e7bdf, 0xfe799ac5, 0xd0245f02, 0x26dfe179, 0x9fa9bc63, 0x7bdf57a4, + 0xfe6fdcae, 0x3b3fe84f, 0xfee7a625, 0xf685bc59, 0x4efb2937, 0x0e3cfd94, + 0xf3fb130b, 0xae33fe6f, 0xfcec57e3, 0x8e9641fc, 0xae33707d, 0x3a06b90f, + 0x88e57ac7, 0x573fe281, 0x2e7bf026, 0xbf7b7f6f, 0xedf2f51e, 0xff0114a8, + 0xe44b67b7, 0xaec51d1f, 0x6d1da347, 0x80257da6, 0x1f9811bf, 0x1ca9a8c9, + 0x333ee78f, 0xe19678b7, 0x17de36d3, 0x6dd20efd, 0x7bf74c9c, 0xc6a3db34, + 0xc0fa3ae3, 0x71819659, 0xa9ef5877, 0x1621e67d, 0xd8c6f583, 0x18fdc863, + 0xb1f9f75d, 0xe8c70099, 0x0acdb223, 0x0fefa6f5, 0xf77cc50d, 0xe63af5c0, + 0x0c6be154, 0x73c32cf3, 0xed5ba33e, 0x22ee1133, 0x2e305fb0, 0x71b8d45f, + 0x2e439e19, 0x7b512f5a, 0x2939db97, 0xbdb3e61c, 0x4349b3fa, 0x3d401f50, + 0x9eb5c6ec, 0x48d573d7, 0xcf394c36, 0x24675c6f, 0xefc3517d, 0x91eed86f, + 0xebf79998, 0xdbbf4331, 0x2cfb43d7, 0xd05b638a, 0x7cd5720e, 0x5cdffb46, + 0xdfb52700, 0xccc5cfc6, 0x94567687, 0xa9fb9a97, 0x12f5e2bf, 0x457323c3, + 0x543af8db, 0xc360c474, 0x9f7b75ef, 0x2a74f5a5, 0x8a90978c, 0x02778eeb, + 0x884739c5, 0xffc77b7d, 0xed5df90f, 0xd58fd38c, 0x2feb92fc, 0x9fbf2989, + 0x4f9f57ab, 0x97d3e8eb, 0x2db10bef, 0x3f414631, 0x498a8cef, 0x7d5f11d5, + 0x71b4e746, 0xf013935f, 0x179c547d, 0x8cea3fdb, 0x409f7d51, 0x4f3f2b2f, + 0x8e30d05b, 0x321551ce, 0x9aa39d07, 0x8fdb9a36, 0xc828feef, 0xde33fb83, + 0xe37af835, 0xe23ffdfb, 0xb6dcd3bf, 0xb6dfeb9d, 0x1fda16e4, 0x307f1e7b, + 0xb65c6009, 0x717d265e, 0xce819b7e, 0x7018c90d, 0xe76dfc44, 0xf5fec5f6, + 0x5bf3dfbc, 0x7e361db8, 0x70931dc3, 0x59b05dbd, 0xf5c46739, 0xce3fe2b3, + 0x62f388b7, 0xfc8d1b95, 0x5fefacde, 0xac3d1477, 0xbf911efc, 0xfceb2d9e, + 0xc92f6cfd, 0xffad594f, 0x2ed0ccf9, 0xefe9043f, 0xb9f88afd, 0xa18188fc, + 0xb99d221f, 0x4f8ff944, 0xef871d70, 0x3b251ba3, 0x3a2a3b9e, 0x1d90f26e, + 0xdf7799ed, 0x393d71cf, 0x3afba261, 0x1cf055ce, 0xef9328f6, 0xf781bf2f, + 0xe3351c9f, 0x97e03cce, 0x05ef8479, 0x3be1116c, 0x473f336b, 0x2ab47597, + 0xe7ae3e76, 0x7fdc7813, 0x9cccb541, 0x89f0fd2a, 0x37799f64, 0x1ee8175f, + 0x598e856b, 0xb8f9cac6, 0xe562de9e, 0xd9bad8fa, 0x2fcde740, 0x760cfd08, + 0x5103dd3e, 0xac5d6bbc, 0xe2ff4551, 0xf8b175a6, 0xc42b2853, 0xe265b439, + 0x91b17a9c, 0x47bc538f, 0x8d546cb2, 0xf4a3f4a3, 0xdbc5dc6b, 0x67f135a5, + 0x2317fd4f, 0x2fcf347c, 0xfc27a88c, 0x7e36e9fb, 0x7a8cfd0f, 0xee155aff, + 0xaef51817, 0x8c72974c, 0x2d35333a, 0x0f643ef0, 0xd31fcf8f, 0x747f7e69, + 0x35825fd4, 0x6cba91f9, 0xdfa07790, 0x4edc0d6d, 0x653ecbab, 0xb2a2cb2c, + 0x5cbbe505, 0x27cb85c4, 0x75f57df0, 0xa3974719, 0x92cd4fbc, 0xdb981f88, + 0x29dfc469, 0x8accbb07, 0x5905a779, 0x6802fdbc, 0xf758728f, 0xd04b972c, + 0x1fd4560f, 0x830017ff, 0x8000007b, 0x00008000, 0x00088b1f, 0x00000000, + 0x7cedff00, 0x55537c7b, 0x393ef0b6, 0x526d3479, 0xa0fa5b42, 0xb4db4e50, + 0x9494b14d, 0x27457897, 0x880b5a3c, 0x46107006, 0xf4228206, 0xbd185499, + 0x35fde338, 0x9c414415, 0x0e7c570b, 0x42d2d37a, 0x1429a2c1, 0x20d5b16c, + 0xb47441d2, 0x3bd15ef6, 0x0f8afea3, 0x52d25a04, 0x8ef4f987, 0x6b5adfa3, + 0xa126d39f, 0xdf7ef515, 0x37f5375f, 0xef6758b3, 0xbdeb1fb3, 0xce275ef6, + 0x620a3b5d, 0xd67318e3, 0x319e920a, 0x6abd54d6, 0xc614f273, 0x2c8ba68a, + 0x67e7c242, 0xf01192b4, 0x2c7133e6, 0xd3e3b187, 0x1939db3f, 0x74339dda, + 0x7ff41d26, 0xc637d357, 0xf3ec6064, 0x991cc64a, 0x5ea5b388, 0x698459c0, + 0x8c09e2c2, 0x060e313d, 0xead8ca99, 0x0c0599e6, 0xeccddf9e, 0xf8bfb19b, + 0x7981f436, 0x47a20d5d, 0x2e9c0027, 0xc60dba8e, 0xc680f77d, 0x7e3b280a, + 0xfdda8e83, 0x153da007, 0x4faed8e0, 0xdcbfc004, 0xe86e61a5, 0xc89771b0, + 0xb2fff418, 0xc5f7a05e, 0x90597ee7, 0x3adaf804, 0x2983aac1, 0xad9aef8f, + 0x1efec24d, 0xd9bc61c0, 0xbc6869cf, 0x7f78fbb5, 0xc5e433f8, 0xf186b633, + 0xe2a635bf, 0x632e599b, 0x65a7cce5, 0x69efd0e9, 0x115da7cd, 0xf87bedbc, + 0x1827b15f, 0xc60fad2f, 0x4bb6d9cb, 0x6f403462, 0x750ef3f0, 0xef386dd7, + 0xb4f41bfa, 0xb637d9ee, 0xeb8f5e9c, 0x5c30d06e, 0xef1bece7, 0xba02ef8f, + 0x963351ae, 0x8e90693c, 0x0cc788e5, 0x559d8eb1, 0xb31fa4da, 0x1c75909e, + 0x3b8c6719, 0x63fc0d7b, 0x3df49b12, 0xb8dcee90, 0x628d8c91, 0x740b5dcc, + 0xb67e0049, 0xf00f360a, 0x4765b8a5, 0xf3d616bc, 0x02fdfe3d, 0xf11db6f0, + 0xb6d73c22, 0xbd2fd408, 0xad62c38d, 0x60aff16d, 0x0aafc51f, 0xb0696aa6, + 0xb9ce32bf, 0x7df10271, 0xbfef3373, 0xb5e015b1, 0xac5f8fc3, 0x0ac6bedd, + 0x65dd4a70, 0x72b864ad, 0xb17e651c, 0x739c782d, 0x8e857cb2, 0x2c1a2f97, + 0x10bba46a, 0xaf7e4569, 0xadbcb817, 0xdc799bbf, 0xacc94f20, 0x87406042, + 0x9013e644, 0xbd29c0df, 0x86fce41d, 0xcb55903e, 0xf17edd20, 0x1d5b0475, + 0x6c99c740, 0x3b3e1064, 0x7fa82922, 0xa83529be, 0xecc4a6fd, 0x52b9f6a0, + 0xdf3e105e, 0xff505d72, 0x4199d605, 0xe7d3adf8, 0x685ff506, 0xdb84185b, + 0xeb8d4998, 0xba5cad6f, 0x999073f8, 0x041d2b57, 0x70287a15, 0xd8c54e86, + 0xee0bc13f, 0xa036ec9b, 0x19288ccf, 0x3e397367, 0xd8d1f002, 0x06ddb37e, + 0x20919d74, 0xc7016ce3, 0x05f69593, 0xe538ffbc, 0xfb785bfd, 0x2dfb4a35, + 0xd2a27dbc, 0xafc72b7e, 0xf1eed467, 0x03776adc, 0x8ed1ebfe, 0xb6f8096a, + 0x138aebe4, 0xfde9a023, 0xa77745aa, 0x45583f02, 0x18d36306, 0x0034875b, + 0xed182ed6, 0x351a4a78, 0x7ff4aed8, 0xe357b255, 0xd14bdef3, 0x63226cb9, + 0x51dfc80d, 0xe6321f3f, 0x716779a3, 0x1159b2d2, 0x33ea1f06, 0x0cf4d08b, + 0x631a51e8, 0x0db18d82, 0x906f4831, 0x0477a213, 0x89a55f41, 0x8995ebe0, + 0x94a8df04, 0x63336ad8, 0x821695ed, 0xf4ad2b27, 0x74e554fc, 0xda576f82, + 0x5953be08, 0xd2a3b048, 0xe290504e, 0x9f1872d8, 0xa23eb1ed, 0xd5b87a41, + 0xfcc2cf23, 0x7e40cff8, 0xd4c64286, 0x1722acec, 0xcabf79d0, 0x65f48ad6, + 0x6ce98c6c, 0x5ef3e0d4, 0x815243a1, 0x46a7bade, 0x0f40eb58, 0xf37a0f8c, + 0x4617a04c, 0x11bac1a7, 0xe59c6168, 0xbb43524b, 0xbad69d71, 0x029fda11, + 0xf587ab73, 0xda991ad4, 0x1cc9f602, 0x34f1100f, 0xf7aa8d0e, 0x7fec0552, + 0x1ff5045f, 0x0236c603, 0x196825fa, 0x7de0f7c3, 0x1ffd8116, 0xdfd81163, + 0x684024fc, 0x10e1adaf, 0x37f48224, 0x43cde741, 0xe2e09efb, 0xd555d8eb, + 0xee304921, 0x5c7ca9ae, 0x29f13158, 0x8119cc5f, 0x499fb2f6, 0xb8394c23, + 0x005abd1f, 0x83d5e881, 0x2bb009df, 0x45034f59, 0xdb24f402, 0x01d4c113, + 0xbd4d757a, 0xe09f0829, 0x3fea0c4d, 0x6a0a59b1, 0x8259f3cf, 0xb49f27da, + 0x3b53e106, 0xbff507a6, 0x105b43f6, 0x61575d7e, 0xcfebff50, 0xfef083d9, + 0x618fd81c, 0x94defe78, 0x9ff50428, 0x703ade0b, 0x89aac67c, 0x232df33e, + 0x1bf79e83, 0x1b869d38, 0x78358177, 0xb71f855c, 0x7f1e0f4e, 0xdc782da1, + 0x3d87cb1f, 0x906a27a0, 0x13d07aff, 0x4f41fb84, 0x0de720d4, 0xbf8827a0, + 0xd0827a08, 0xcf827a0b, 0x209e820f, 0x827a04de, 0x13d011f8, 0x4f419bc4, + 0x3d051e10, 0xa357e7c1, 0xef3cbb57, 0x53de7949, 0xed8cbcf2, 0x8d5d3a20, + 0xefcb6f2e, 0xdfbf23bf, 0x079bef81, 0x30bcb0e5, 0xc835f543, 0xf398ccf3, + 0x87582eda, 0x01575d6d, 0x6f7d4dc6, 0x8246ac8a, 0xc9cf0e6e, 0x5aab8c4a, + 0x9456d962, 0x5bdf7b5f, 0xa70fc42a, 0xfb42b69b, 0x78ffe696, 0x4dfddb07, + 0xcdf184a2, 0x459fcdeb, 0x5f3d38e3, 0x2c753247, 0x3459f7be, 0xdf654bc6, + 0x42b7c230, 0xb9c5fa3b, 0xe5f3228d, 0xb57bbaa0, 0x5663ded8, 0xe3168f70, + 0xa3437b33, 0x5a52f916, 0x6fed48df, 0xedc1357a, 0xed41d5f5, 0xb00fec26, + 0x4689ed54, 0x56685e7a, 0xff51f3c6, 0xc3f73332, 0x6f8fea17, 0x5bd61ebe, + 0x562ab8de, 0x3697f584, 0xd77f17bc, 0xe2ffd00f, 0x1c721791, 0x0b797ef0, + 0x1c18678c, 0x2345bcaf, 0x65fd7ce3, 0x1882c6e6, 0x621a1ba0, 0x87acfcb0, + 0xc01b676d, 0xd736942e, 0x577c6195, 0xc343b96a, 0x5ebd3e80, 0x01d710b1, + 0x71062a7f, 0x9189995b, 0x7ef1e87f, 0x8c177d15, 0xc4f79afb, 0x7a87e82d, + 0xe3478f5b, 0xd04dbdbc, 0xabbf803f, 0xb11c7953, 0xfc4b553a, 0x1e3a69eb, + 0x16fb412d, 0x774e71ef, 0xfff68fb5, 0x02f78cba, 0x8b377a24, 0x5afa2e3c, + 0xc6507c45, 0x9a33a173, 0x4619ed8a, 0x97a757dc, 0xaa7f77cf, 0x579b9fc4, + 0x9ff5c6ad, 0x55365c4a, 0xae05fb24, 0xf1def01a, 0xc2b6ebf3, 0x30bd4a52, + 0xf7f210ee, 0xbb6e3ca8, 0x69bf471c, 0x1a3ed43e, 0x30aa7ee8, 0x807c8f36, + 0xaa636fdc, 0x6815fa8a, 0xe80ae61d, 0x8c9069d7, 0x160fcf28, 0xbf911ba6, + 0xe7c423af, 0x0eb5bb85, 0x7c4d2580, 0x47534ebe, 0x675dca34, 0xe31164d3, + 0x7fbc6551, 0x901de791, 0xb9be01ef, 0x9e454f89, 0x338e036a, 0xfcfe3fc8, + 0xbd1354fe, 0xdef3ca77, 0x7f603b92, 0x2b28969d, 0xcb5da5f2, 0xa5fd708a, + 0xbe7160e8, 0xa46ae4d6, 0xfddf3283, 0x2d7a3f32, 0xbfabe22a, 0xbbf72359, + 0xf5058ea3, 0xd57e70d3, 0xe4c7af06, 0x3bfbf339, 0x73d97fa0, 0xbef8c322, + 0x8f11534c, 0x20fcc7fb, 0x9d32dd68, 0xf8be34cb, 0x2d7900f8, 0x1bd0196b, + 0x8b79c903, 0xf11227a2, 0xa763e153, 0x4aebe445, 0x2c1879d4, 0x8eb1acb9, + 0xced41ae4, 0x4d3907ad, 0xff20ea8e, 0xdccffc97, 0xfc0ad54f, 0xfb2559b9, + 0xb5c7154d, 0x3e2fd100, 0x7853fb27, 0x1f00999f, 0x00146c0b, 0x4fa614d7, + 0x917c4155, 0x21e6362c, 0xb6a9753f, 0xff9854a6, 0xc87ec97d, 0x6489f142, + 0x553e43b4, 0x66e0d97e, 0x7efed023, 0xdbce24f4, 0x047904df, 0xd11e5bcc, + 0x9073ef3c, 0x282b7ecf, 0x7fb7ac08, 0x5ce28697, 0x00833b10, 0xe99acd71, + 0x94be5f5c, 0x8844d31c, 0x54abcb17, 0xc832afb4, 0x5f98f4bf, 0x62eef6c9, + 0x28adea63, 0x452765a7, 0x2be60453, 0x9d7fd4de, 0x86837881, 0x57a72af2, + 0xff30fab0, 0x255a326b, 0x9deacfc0, 0x9d379869, 0xe2d3eaad, 0x3e21677b, + 0xcbcf9c7f, 0xa7cb4f50, 0xd4519f73, 0x193da3bc, 0x57e60960, 0xafc8cfe2, + 0x3a99f242, 0x8c75c7fc, 0xf21539fd, 0xb26f8c1a, 0x37c63659, 0x048ce2f9, + 0x7f995fd2, 0x1710276c, 0x13f5a612, 0xdfa809ac, 0x3cd2d45b, 0xab6f77dc, + 0x71f484c6, 0xc62a1db5, 0x22ca7b75, 0xafd82aad, 0xa251c373, 0x815fef63, + 0xf65710ce, 0x33ca3226, 0x67a7197b, 0x6797336f, 0x44f04697, 0x9e20fbe0, + 0xe0845e34, 0x5ea682a9, 0xd9347f77, 0x510ac621, 0xcb2dd7fe, 0x68bc6150, + 0x80337203, 0x57b91447, 0xf5c0a5fc, 0x977546fc, 0x7bde1238, 0xe7fdc343, + 0x48d353df, 0x9968e7ee, 0x46f5f103, 0xc62bf92b, 0x887de8aa, 0x52fe28a7, + 0x67c435fc, 0xc7254f14, 0x147e497a, 0x6d50bc3f, 0xab8e04d2, 0x821bdfbc, + 0x0580f32b, 0xe0ede3e1, 0xf8c0def1, 0xa6fc7923, 0x1e740f8c, 0x6afe7481, + 0x70fc958a, 0x91f042ca, 0xa41577a4, 0xf59e8a77, 0x01cd5c80, 0x3810cab9, + 0x1d76cabf, 0x728073a3, 0x00e741d6, 0xde7cd105, 0xf11f9c02, 0xd2130e48, + 0xedffda04, 0xdb5e9c69, 0xa7d8a864, 0xc4b66913, 0x698d8034, 0xa469318e, + 0xb792261f, 0x408cb2f5, 0x35d0927c, 0xf75d7d84, 0xf06e7e27, 0xda3dc815, + 0x08575f99, 0xfe203992, 0x6ed3fd29, 0x69c34b2d, 0x18161d6c, 0xbd7188af, + 0xc5d9e451, 0x1b95b2bb, 0x303992f4, 0x7fc3b2fe, 0x72c567a0, 0x279e117b, + 0xd8e0fe40, 0x27992f10, 0x8f627bc3, 0x4fd73c16, 0x73577396, 0x73d3ee30, + 0x0519f379, 0xffc9c60f, 0xf5e72694, 0xc8a7fcb2, 0x10ed58f2, 0xabdf683c, + 0xee1355bf, 0x90782e5e, 0x8784bf07, 0x45e4621b, 0x99a2bf62, 0xbf47f41e, + 0x8ef29404, 0x2fa4719d, 0xb9fb08d4, 0x2fffde4d, 0x0263bed5, 0xc684e7ec, + 0xc2f98a9b, 0x2b08f289, 0x418cbf8e, 0x64f60180, 0x7820eb39, 0xd879ca3a, + 0xc7bb8347, 0x81ff3c62, 0xf8c56743, 0x8d537aa7, 0x2e66ed11, 0x3cc264db, + 0xff514805, 0x9f1fe4fd, 0x0b8830cf, 0x5f0aff90, 0xcbecd31b, 0x073f00d2, + 0x749c493c, 0xefa5fbe5, 0x3e468e1f, 0xd0e6ff76, 0xda19db92, 0x3bb23e9d, + 0x1a551525, 0xa8c41c9c, 0x906d32c3, 0xe0bf0abf, 0x1f1052df, 0x90630f61, + 0x42cf622e, 0x177ffbd2, 0xabb1fa19, 0xf3a151f1, 0xac7e642f, 0x21f6e16d, + 0xdd0abf94, 0xa21e676f, 0x5daff81f, 0x23a617c4, 0xffca147b, 0x0407f1ab, + 0xcd363971, 0xe431d38e, 0xdb8ab26b, 0x2035e4ab, 0x3beeb02f, 0x0bada398, + 0x8fa892e0, 0x32e72434, 0x7ccb969f, 0x167980fa, 0xdfff5258, 0x9a44e9f1, + 0xe91a7b63, 0xfd4869ad, 0x32c7d50c, 0xe2aefac9, 0x67a43c6f, 0x3579fac1, + 0xf85664bd, 0x8e7f802f, 0x7fa4d10d, 0x625d7f0a, 0xd5f7e903, 0xad18f3cf, + 0xf059bcab, 0x847f52f8, 0x10b00a5e, 0x884363e0, 0x1afc2a3e, 0xf6291ece, + 0xfb96b4ec, 0xa27df763, 0x8ff2f307, 0x1309df05, 0xceeca7da, 0xd282640c, + 0x8eaae3ff, 0x38c0f7b1, 0xf0e4cf1f, 0x0159c634, 0xad922db8, 0xa49e23b4, + 0x3f7ee373, 0xa167b216, 0xf858fe7f, 0x9e385be7, 0x5f1095a0, 0x04cb3096, + 0xef0d69f8, 0xc57dd8af, 0xecbc7fde, 0x4fd439da, 0xbee06f60, 0x47a25c60, + 0xa782fddf, 0x256a4406, 0x5f5c6a98, 0x0aa7acea, 0x27f9e0d3, 0x43cf4dbf, + 0x05d6d87e, 0x2e7e878f, 0x3ce22275, 0xebf1baef, 0x9caacd3e, 0xfc0679c1, + 0xf44b9cd4, 0xfd53f15c, 0xb25a1965, 0x2833ab53, 0x69922fde, 0x1ec98b6d, + 0x87f829f1, 0x08fa4f7e, 0x5fa0ce55, 0xc8793fe9, 0xefa008e0, 0x4c3bf079, + 0x3f67801b, 0x97e81296, 0x3479ed8e, 0xa451f913, 0xb9e2e775, 0x3feab9e3, + 0x2edfa0a4, 0x2670f3da, 0xb67b8dc5, 0x5ffc6264, 0xa668f354, 0x0728f08d, + 0x4e6a1fe5, 0xd703ee87, 0x101adeed, 0xf26526a7, 0xc47979f8, 0x1f8c7cb1, + 0xf1735de7, 0xcbf41321, 0x4260adf8, 0xeb35f831, 0xddfd0878, 0x77970b0a, + 0xec8233b6, 0x43678c31, 0x2f65d7be, 0x3d7d45a8, 0xb34cf965, 0x74bfe31a, + 0x056bd135, 0x804b6cf3, 0x6088f676, 0xfd8163aa, 0xff6356c7, 0x6d049b55, + 0xb1fa1c62, 0x97987991, 0xd247d2e9, 0x247cee3a, 0xaf9f1daf, 0x9f3f8078, + 0x7534f3a7, 0x694f38e2, 0x37a475ad, 0x278c34f6, 0xd2ebf595, 0xcadef4b5, + 0xcbc5026d, 0x4f193cca, 0xee0757c6, 0xfdce9753, 0x8db29b32, 0x32adcfec, + 0xe07e6e5f, 0x611237bd, 0x1d6349dc, 0x7f6874c6, 0x66b389e7, 0x139f3c1f, + 0xf3073e73, 0xe3ad0c86, 0x77dc62d9, 0xfb8ace8d, 0x2c9b9298, 0xdfff6026, + 0xe11c7ccc, 0x3d5607ca, 0xf2768c5b, 0x73ca08e9, 0x13adf594, 0x83e61524, + 0xbf6fabc7, 0xee76e913, 0x778a0889, 0x256755d7, 0xdfc81fb0, 0xa5ff02f7, + 0x41f6c64c, 0x05f08efe, 0xd825dfc8, 0x44ca81e2, 0x94aa5fc2, 0x5ca5b208, + 0xb899d6be, 0xbc6e193d, 0x4b9790c9, 0x3ca64760, 0x7c41e302, 0xcd9c6f38, + 0xcaf40e92, 0xb35e5f18, 0x0657de45, 0x4ee79fbc, 0x98748d9d, 0x769ee5b2, + 0xd2e31d0c, 0x56f2fe79, 0xa82923e7, 0x381f6bc7, 0xb4317cf3, 0xe7b74aaf, + 0xbb11fbe1, 0x7e3e512e, 0x15e1e5bc, 0x1aa2ef48, 0xbc9fdf1d, 0x644f73ef, + 0xe78b3c26, 0x286a6f75, 0x3aed763f, 0x8016fcf3, 0x47bb6d77, 0x3fef281b, + 0x7113bf76, 0xba7f533d, 0x97470d9e, 0x8f67ae9f, 0xd53e90a6, 0xfce59e80, + 0x3d733d7c, 0xdcf44550, 0x15ff6e9c, 0x8d39dbca, 0xebf5053b, 0x240df65c, + 0x8136eef7, 0x5fd8a1f8, 0xf2a5fde5, 0xde554bfe, 0xce02336d, 0xc6432f15, + 0xd63ef486, 0xc62665f2, 0x979b97b5, 0x47dc088d, 0xfb023c28, 0x35864c86, + 0xda7dbd03, 0x69a7db2b, 0xd856e91d, 0x8f1534df, 0xabdb4367, 0xbdb255d2, + 0xcf0ffc85, 0xc5ff1433, 0x0f78b43a, 0xf82ad651, 0xaa3ef122, 0x6af3a6f9, + 0xd81257ba, 0x7de741a7, 0xe01a7d8c, 0xe75b8777, 0xc713a0d5, 0xe3da0f51, + 0x31543f6b, 0xbdbf805f, 0xf9922bae, 0xc81de602, 0x114f6023, 0x4b7f1fc0, + 0xd87d9052, 0xe7042e9e, 0x36aef013, 0x15f21fa0, 0x2dfc65ef, 0x9f8835d9, + 0xfb3e72d7, 0xc47c408f, 0x389849cf, 0xe71e906d, 0xd173ba5b, 0x70f42b2e, + 0xb926ed1e, 0xf87e6b29, 0x99f44092, 0x7b9d5e7b, 0xdb1cfa75, 0x7c8b9dd3, + 0x9ae9af3d, 0x5f947986, 0xfc8b95db, 0xedc2be71, 0x93a54ffe, 0x11f8bcf2, + 0x05d800d8, 0x3ca260a7, 0xa1ec5f2f, 0x927fdcbc, 0x96cee5e7, 0xfb7764dd, + 0x88b9f95b, 0x9051d54b, 0x1508e780, 0xeed1da67, 0xfcf227f5, 0x21b7c609, + 0xcba466bd, 0x97dd53fe, 0xdfec10b2, 0xe1390189, 0xd439da79, 0xe38e2d73, + 0xc17b432d, 0x1d58a372, 0xf501778c, 0xd8af9e1e, 0xe519ba90, 0xd4679cff, + 0x6fa3b424, 0x49ddfee5, 0x45af68e7, 0x638a4499, 0x7f0069e0, 0x11e1f607, + 0x1e282d99, 0x80b6628a, 0x74ad2e7e, 0xa7bfc52b, 0x74c7ba44, 0xc67ae78d, + 0x2b3d728e, 0x9b4c74df, 0xa35e3018, 0x7894f76c, 0x7f6bde70, 0x345d7d27, + 0xf023b991, 0x14f597bd, 0x2031b0e7, 0x7a2f80ff, 0xf283c139, 0xdca8f7e0, + 0x178bc81a, 0x87fee64d, 0x7ef1d21d, 0xa454d289, 0x6af31f87, 0x4c794fa0, + 0xc00c6647, 0x2b89df23, 0x4e4f98ed, 0x2be01c02, 0xf2cf9702, 0x23991d45, + 0xd0495cf1, 0xa4bcf0ab, 0x77b786bc, 0x54bc78aa, 0xf7dfc69e, 0x7b57dc0f, + 0xde821653, 0x9cbdb6f5, 0x5be02772, 0x9c35be0d, 0x7c4cbe0f, 0xb99eda0e, + 0x46efe608, 0x5cf74d9f, 0x5ed08be5, 0xdc151b75, 0xf78c71c9, 0xb5cd9ee9, + 0x5baae508, 0xbc15e0af, 0x5c64105d, 0xe5c15f79, 0x8c8547f7, 0xb4859237, + 0x0a4ff487, 0x3dca35c1, 0x58ff3c9c, 0xb517fefe, 0x7bc22cf7, 0xcf3af9b7, + 0x57f44ac9, 0xd218692f, 0xf0e07f55, 0x697fa459, 0xb33bf70b, 0x39ee1c0e, + 0xd872f288, 0xb1e6f748, 0xe3e254e6, 0xdbbd96c6, 0x375ca126, 0xada073f2, + 0xff3fef0d, 0xc3a7ea3b, 0x57183163, 0xe69eb759, 0xebca2f9d, 0x1e39eb66, + 0xdfb3b725, 0xb2847c72, 0x3c71dfaf, 0x6b7fb796, 0xa75a17fe, 0xfb81f0ff, + 0x9fa05e50, 0x17a5e29b, 0xa2605e40, 0x73d94392, 0x1bf59e30, 0xfce0563b, + 0xab3afdce, 0x09e7c25b, 0x95be30b3, 0xa4dcfccc, 0x14f6fc78, 0x4754a7cc, + 0x1df9edf7, 0xd7efbb9e, 0x2ba139d3, 0x12a5db86, 0x3dda7ab1, 0xf7bb3f24, + 0xb5f701fc, 0xf6e74f4f, 0x1edcd1c5, 0xa0c9ef15, 0xfe579ef3, 0x940ad9f1, + 0xd7717c83, 0xd7fe7c1e, 0xe90abd5a, 0x8db5a9d4, 0x4cfd01b8, 0xa9e286a7, + 0x3e2f1962, 0x13d7cb1d, 0xf24055d5, 0x653db713, 0x4948c811, 0xe0b7fdec, + 0xdb8be7ba, 0xce7f479f, 0x0ce8eaf6, 0xa03efceb, 0xbe77bc2b, 0x2da7434e, + 0x35467dfe, 0xb0b76bca, 0x38b3c57d, 0xd7ef1d7e, 0xf44edfad, 0x3165d776, + 0x31fa0f9c, 0x16ea9f3c, 0x3f3d0476, 0x1737b75f, 0xfb0bade3, 0xa5dc53e7, + 0x97a293e8, 0x20bab525, 0x293fc7fd, 0xf963f31e, 0x8666e4cf, 0xc2e9fc80, + 0xcffc6791, 0x85f5e806, 0x0b4f8d06, 0xb1d62a34, 0xa7af784d, 0xf24963e8, + 0xbfb8854d, 0xe6755512, 0x278bc03a, 0xbd40ad77, 0x1167af3c, 0x2defd089, + 0x2e0f3f15, 0x885aaa69, 0xf5b87b76, 0x7c799b14, 0x9f913979, 0xd66e5f97, + 0xa9cf027b, 0x9547e143, 0x3d5b7a4c, 0x42baff88, 0x19473e47, 0xb7ad2def, + 0x670ee30c, 0x9fc3f70c, 0x3306ff40, 0xee6661c4, 0x086e56a7, 0x1cdcbfee, + 0xda9dcf43, 0xcbb44cae, 0xcccbf8ca, 0xd4cf6e26, 0x9fe8995d, 0x7923df43, + 0x82f57b47, 0xa4aaf640, 0xf7433849, 0xf8d248c7, 0x44967a41, 0xee623db8, + 0x9c487cd0, 0xc601f326, 0x77ac87fa, 0x9b7a0d25, 0x8d29c61e, 0x7f468aec, + 0x8aec6655, 0xff6f73c6, 0xc8d59151, 0xc6538bec, 0x4f9c1b4f, 0xbd8b8fc9, + 0xa87e9b1a, 0x183b60f9, 0x7fc5adef, 0x32622903, 0x3514deb8, 0xcc7cd147, + 0xe50d35d4, 0xf05768b6, 0x534fb87b, 0x9bfa3e80, 0xc607c777, 0x75c7bfa1, + 0x8677de53, 0x1ff7a6f4, 0x1ca0a69f, 0x26d8a894, 0x20bee73c, 0xc0617bf0, + 0x82f85ee9, 0xf25e5e7c, 0xca244337, 0x65cb85cf, 0x01fec7a4, 0xd928fb3b, + 0x6762bf07, 0x15c70d59, 0x7076cb3b, 0xeecec07c, 0x3762b8e2, 0x42a3fe95, + 0x1d0a4fde, 0x9077a94f, 0xe6ed93c7, 0x6e7abaa2, 0x7f7e4537, 0x4c6b76c7, + 0xfce27f3c, 0x19d32b5a, 0x95d3b412, 0x123577e4, 0x19c5b1fa, 0x76a579ca, + 0xa0e27e90, 0x7499fa3e, 0xbbf509a0, 0x10f940c8, 0x070d15c4, 0x59791cf1, + 0x07ef15bc, 0x9caee943, 0x7cc5c777, 0x7cf906b3, 0x8af1d6ab, 0x7269ef19, + 0x82afc8ba, 0x74bf90b6, 0xb8a3aabe, 0xb7d357aa, 0x965fed07, 0xf61af1d6, + 0x6c76d32b, 0xea4b029e, 0xe3b574d1, 0x943cd091, 0x5c43b257, 0xbb39fd5e, + 0x39527ce9, 0xe6577f2f, 0x5ea70323, 0x7025f28d, 0x7cde3939, 0x57b46de8, + 0xf2748efe, 0x03e45703, 0xa3478fcd, 0xe210f9dd, 0x5c407714, 0xbdaae1fc, + 0x14b50f74, 0xde011fef, 0x7f7829b9, 0xa62edffd, 0x0b6d8838, 0xbcf28e78, + 0xa50f1833, 0x2fb5ca0b, 0x24dc8f48, 0x9ba5dfc7, 0xeace9608, 0x061d2270, + 0x8b8045f0, 0x21ebf801, 0x667f4878, 0x1e6266f7, 0x08d61dfa, 0xc6ca3d01, + 0xbc534efa, 0xd0c3407a, 0xbf046c3f, 0x28e1f849, 0x1d532baa, 0xc718bf00, + 0x9bfa22fd, 0xca0ee8d2, 0x7587fceb, 0x60f0df74, 0xb82997cb, 0x8ba6bf7f, + 0x96d295f2, 0x9e31e397, 0x344b358d, 0x78dff83e, 0xdc3d8fba, 0xb6318f12, + 0xe54cbcf2, 0x94eb94cd, 0x28fed172, 0x5f45cbcf, 0x54bfae26, 0xf6c5c8e8, + 0xd453b458, 0x7111701f, 0x1328fb46, 0x2d60ddb8, 0x5089f922, 0x706745be, + 0x25f60bbb, 0x8f11ee97, 0xb15978f2, 0x605f6427, 0x79f1d7bc, 0x261fb70e, + 0x5e14fce5, 0x31bb462d, 0xa4d99d84, 0x41564dd8, 0x06644d79, 0x3ef2b75f, + 0x30f3cb8d, 0xd2be776a, 0x83969b9d, 0x7bf249ef, 0x7d2cf601, 0x1da13ed0, + 0xf23b2449, 0xf61e26a0, 0x60bcf255, 0x14af08dd, 0x802aaf2f, 0xfaad6cee, + 0x2fca029e, 0x19ee9b99, 0x8575d742, 0x7f39997e, 0xd2f3e44b, 0xbcfc3d92, + 0x9f8682f4, 0xf2bd832f, 0x3b5afda1, 0xf500aaa7, 0x72b8eeef, 0xdcb9e06d, + 0xb35fc6d5, 0x5b5f1833, 0x30905551, 0x6c979e84, 0x8a3ed1d8, 0x1d17e10d, + 0xd2f105d5, 0x7595cf95, 0xeb2bd05f, 0x1519a59c, 0x55a58f48, 0xae00a305, + 0xf4b9f88d, 0xd0befbe0, 0xdfa1f3a2, 0xf9d2fa06, 0x575f8de9, 0x5c3f9d04, + 0xe662bc6d, 0xe1c2f3a1, 0xcb0a1fd6, 0xcc69df04, 0x57e818a3, 0xe819e91d, + 0x2f7cc04d, 0xb4fbfeca, 0x9e78a04a, 0x871aad15, 0xac7301f9, 0x6b7e871a, + 0x0c0178b8, 0xdd1568e5, 0x8209ba49, 0x0eb0ae1e, 0xffa50f41, 0xbcfc191d, + 0xaf5945e1, 0x7d2fcf46, 0x9fb420e6, 0x19456c96, 0x5c28a8c0, 0x8945e623, + 0xda183c23, 0x7203be53, 0x036394ed, 0x5f7cab43, 0xbb522858, 0x586459ab, + 0x8d12caa7, 0x57d80c9e, 0xf54edb21, 0x7798f37b, 0xa9791506, 0x3d7f7ebb, + 0x4d7fcfb4, 0xd195bc9c, 0x37e50f7d, 0x330e9105, 0x5fb055c6, 0x4ef43f39, + 0x7e701859, 0x37f647b7, 0xfc814433, 0x14525f40, 0x5dced39d, 0x503cbe5a, + 0x10853b4e, 0x72fa79ba, 0xf5f1bf29, 0x6dd206e5, 0x15516bc9, 0xbcc80e74, + 0xcc049653, 0xaf0672f3, 0x696af89f, 0xb8979d06, 0xd27bf32e, 0x27dbf17c, + 0xd7588f31, 0x80af7906, 0x407ea7e3, 0x2f906675, 0x0dd09c62, 0xcc1ce9f9, + 0x66cc1df5, 0x61387b43, 0xae7be514, 0x7ac30203, 0xae8b6733, 0x9d9bef06, + 0x8c78ae9a, 0xbf34b673, 0xec3f45af, 0x569efc3a, 0x92abbcc2, 0x2637f5c9, + 0x05d7d215, 0x5bbf40ec, 0x01f59cde, 0x93f2b5da, 0x5cb0d4fc, 0x3fdd1efd, + 0xce14b9e2, 0x48d4da57, 0xcc658df7, 0xd65f7247, 0xf6ff9c10, 0x075d0e27, + 0xa76cb2f4, 0xd3ee7c14, 0x225fcf3c, 0xb72f0ab2, 0xce9f148b, 0x73a04c4d, + 0x38f7c1d8, 0xf7626d7d, 0xdb6e7843, 0x0558269b, 0xd237aa18, 0x26e309bd, + 0xc73f2677, 0x85f57ded, 0x7ce86b29, 0xeb0533c4, 0x73e57ba4, 0xec8fb9fc, + 0xeb018b50, 0xebcadb99, 0x59237a17, 0xbbe211d1, 0x23f20c63, 0x92ded52b, + 0xb6967181, 0xf1eb9def, 0xaf8e59de, 0x57b1f743, 0x253e6fbe, 0xbacae9c7, + 0xf32727e7, 0x21e618f3, 0xf3976a39, 0xda0a9b62, 0x4cd3ee03, 0x77528299, + 0x046befc7, 0x9c3e8f7e, 0x17bd617e, 0xbd623bd6, 0x72fdc217, 0x7bd6245d, + 0x5ca2fe21, 0x5ef58917, 0xbdeb1cf8, 0xeb926f10, 0x0bdeb122, 0x42f7ac71, + 0x8bae5478, 0xa54b853c, 0xbfd2eef8, 0x3edb9e61, 0xfc721f10, 0x3e084c74, + 0xe9ffb83a, 0x1f182118, 0x33ff502d, 0xcdfe9775, 0x1675839d, 0xf0dfd926, + 0x9ce50b3a, 0xb670b3ab, 0xb1f20779, 0x3c24c275, 0x69266747, 0xb74bea04, + 0x56ffe7cc, 0x1da02fdb, 0xe47d1160, 0x64c4e797, 0x78bb408f, 0xba62e4f2, + 0xd38feb87, 0x93bc3e91, 0x7ec3e8ee, 0x9e6f98ae, 0xeb06cc3f, 0x265a66e6, + 0xfc029a6f, 0xe4106998, 0x44fb7238, 0x059f72bb, 0xbadd99fc, 0xdb9a8a6a, + 0x994e130b, 0xc6ad962f, 0xe925d771, 0xaa1e6327, 0x1dfc734b, 0x5fe855c7, + 0x19ad7a30, 0x48d76fe7, 0xeabc601f, 0xf3cf13fe, 0xa501fa95, 0x33a927df, + 0xdef099f5, 0x26fa4b5c, 0x2819ebcc, 0x4dbc8a1f, 0x3e501acb, 0x6128aa6c, + 0x4933d923, 0x67d5fb8d, 0x92cefdf2, 0x4f80fdf8, 0x6063a92b, 0xcce45f7c, + 0xdb77cc38, 0x949fbe65, 0xe64a7ef9, 0xcdd1d63b, 0x3a3af351, 0x87475884, + 0x20ea10f0, 0xdd2fbfcc, 0x7149931e, 0xd20a5f72, 0x984ba95d, 0xedc67a87, + 0xf5d20a4f, 0x27c72c90, 0x99d3fb64, 0xefe24f66, 0x54acf8f1, 0x96e81fae, + 0x7d9473cf, 0xbe0def2a, 0xfb05e7cf, 0x6ffee12d, 0x5f645510, 0x5b38e543, + 0x788efb96, 0xbd4abde3, 0x3739c608, 0x261fdc88, 0x41dffaab, 0x6f1c93bb, + 0x90c23694, 0x78a3b3f9, 0x09bd36bf, 0xdb6f6c4d, 0xddce7437, 0x296190fb, + 0x30314fbf, 0x3da11efc, 0xe04d4271, 0xe51fe979, 0x908fc079, 0x9a2cba5e, + 0x3923f61f, 0x423f01c6, 0x144e66f9, 0x9bf923dd, 0xa4fca2bf, 0x09aa75b7, + 0xe1dfd4e5, 0x715fa031, 0xc4ffe3fd, 0xb7f0bfa3, 0x6cf5417e, 0xa4bf6ffe, + 0x722db73a, 0xcdebe1bd, 0x87589d72, 0xbde7c464, 0x60159f85, 0x1c32adbf, + 0x3cfc23b4, 0x686f814f, 0x681de66c, 0x51509ecf, 0x8dd8a2fe, 0x98597d50, + 0xf78e5239, 0x676831ec, 0xc4ec5f40, 0x597d01b7, 0xc1798316, 0x12917da0, + 0x132ea87e, 0xcd598bed, 0xb4420bed, 0xb733662f, 0x7da3882f, 0x05f68841, + 0x417da39f, 0xe20bed1c, 0x47105f68, 0xed1082fb, 0xebff3e0b, 0xd3a75e52, + 0x3f29810b, 0x5c5035c7, 0x7f8ebebf, 0x8dbeb27f, 0xafaddbdf, 0xac0ea816, + 0x94dfe607, 0x509d4439, 0xe4275c93, 0xa2f741dd, 0x15a2c3ae, 0xd6017859, + 0x6dcf09bd, 0xd0277d35, 0x051ab82f, 0xcf84956b, 0xb63ad297, 0x60fd4eb4, + 0xd3af3e39, 0x2fe85558, 0xa3c72f5a, 0xad692bdf, 0x2735ff23, 0xbfcb4da1, + 0x9e181197, 0x71d12f1f, 0xe11728fd, 0x3fba24e9, 0xae5ffb26, 0xad73a0eb, + 0x0a417ad2, 0x35c08efc, 0x7fc512fd, 0xf2b9fdca, 0x57b94bdd, 0xca0ead2f, + 0x6ebc6c9f, 0x4aff718b, 0x9e406579, 0xc3277cab, 0x74d56fc4, 0xc08afe3f, + 0xd7ab8562, 0x36b49573, 0xaffac66e, 0xb4767bd0, 0x16d75424, 0x44febf72, + 0x95d75ca6, 0x6f30f2c7, 0xf5627c2e, 0x5f30c381, 0xe51d76ff, 0x774f609d, + 0x409efea1, 0x9cba0439, 0xb9d3d368, 0xb23be7db, 0xde1f1046, 0xf6489914, + 0xb7d90c72, 0xf2811a75, 0x3597b031, 0xc2ecdef8, 0xceaec8bb, 0xfc8abb06, + 0x93eee454, 0xca2d7b54, 0x1209bae7, 0x1d7cb9f9, 0x93c697bb, 0x9200c5eb, + 0x146fe5de, 0x57c02a3c, 0x2f7d2b31, 0x86c812b4, 0xc6af50f1, 0x75d608f0, + 0xaebc64ad, 0x75a39143, 0x8eef943b, 0x577d10c6, 0xd95cf4c8, 0xb06fc7fa, + 0x1d2ee36e, 0x56490f3f, 0xe4803af1, 0xe7bebcad, 0xf5e0e66e, 0x8b4d9872, + 0xdabd2f94, 0x511dcf05, 0x79f85263, 0xe380948f, 0xa1a53aaf, 0x84fce33a, + 0x8a0e9905, 0xfd50e64f, 0x43bbe086, 0x1f9afefc, 0xeb83878a, 0xec684e37, + 0x3b573df4, 0x73d925ca, 0x9553c107, 0xbb150445, 0xf63fd4ad, 0x88dcbdb6, + 0x0cbbe7f3, 0x62b7a456, 0x83a8ae07, 0xa950e48c, 0x100b1c83, 0xc0cc0aeb, + 0xda0c5363, 0x44ec8967, 0xb273aab2, 0x1bfffb84, 0x3f200eff, 0xe30f2da1, + 0xfc7974a6, 0x43fd92d3, 0x9a2d9fe4, 0xbc3df1b9, 0xf40eda4f, 0x080dc02c, + 0x6d7b2f18, 0x6dbfc622, 0x1a46a982, 0x78ee8eca, 0x5c97eb08, 0x7184c166, + 0xf6e44159, 0xbf1878fc, 0x8ad52d20, 0xccd5dc76, 0x403f2de3, 0x3debf7ce, + 0x55dfc0a2, 0xce9c63c7, 0xea9596f9, 0x351ccee8, 0xacbe7cf8, 0x5fadbd4f, + 0xabe3faf1, 0x38b563c7, 0xade99bbe, 0xc8f8f275, 0x8cd7f9f7, 0x914cb8a5, + 0x8486fe9b, 0xef9b941a, 0x7cbbff65, 0xcc1a7bf9, 0x1cd33b03, 0xaff38dff, + 0xa1e97d58, 0xd0e7da78, 0xd3a9507e, 0x4a83f50f, 0xabfff37c, 0xcaedff3e, + 0x54ef820a, 0x51d8206e, 0x51f6a6e9, 0x735cfc59, 0xfc0ab8b8, 0x10d65c43, + 0xbf4294f1, 0xe4aae221, 0xae3ca9ac, 0x89473cc2, 0xa388aeab, 0x0155df40, + 0x75bb3efa, 0x608f9de4, 0x6b53b3dc, 0xeb0090c5, 0xc81bd7a8, 0x4d64643e, + 0x529e2a1d, 0xf8a069e8, 0x27e99fab, 0x2cb3fce1, 0x1fbc6ae9, 0x0425989f, + 0x3fa80be5, 0x1fd46fb8, 0xea3fa884, 0x39e7b880, 0x14f6a82d, 0x29b82f1e, + 0xbf13d05e, 0x5d815737, 0x662efc01, 0x3d2bb20a, 0x31857621, 0x1d70affb, + 0x9d795a6b, 0x3a5f5297, 0x93d7c00b, 0x5e33b086, 0x46c6676e, 0x3ce1f77a, + 0x54919d63, 0xc3427caf, 0x16c4eee5, 0x9ab82f5e, 0x8ff7f9d9, 0x689bda57, + 0xb15defa4, 0x01fc9f7d, 0xa8f5dffa, 0xcd9ee281, 0xfda66b49, 0xf8cdec4f, + 0x7f0f4e2c, 0xe7de6fa5, 0x22731f20, 0x905cf7f9, 0xee2859bb, 0x7e924555, + 0x8ed97e40, 0x6bac57df, 0x8ed0f211, 0x77d9d1cf, 0x6a9d3ae1, 0x27167ebe, + 0x3baa27df, 0xbf42f78a, 0x2b64f8ce, 0x1263cfe6, 0xffac308f, 0xe61577ca, + 0x64ecbda0, 0xbf7be9db, 0x5dc73a8d, 0x39c5e7c8, 0x7b9d0215, 0x5897faca, + 0x95b35518, 0x153591f8, 0x2708bef9, 0xe6e473a3, 0x2e8f98c5, 0xf1c10a8a, + 0x8dce8b1e, 0x6c78e55f, 0xd2827b48, 0x1cc9e32e, 0x2f356777, 0xd2e573c6, + 0xf3e9bd7a, 0x91cffaa0, 0x39abb841, 0x6079f4c9, 0x03fe2a7d, 0x822daecf, + 0x93dc059a, 0x078e0837, 0x85e53f70, 0x2e39f917, 0x5abf23eb, 0x7d112595, + 0x7ccebd47, 0x737dff28, 0x902e748d, 0x87915b10, 0x472c09e7, 0x52fd8a9a, + 0x17147d34, 0x96ab7ef6, 0x8be8b3bf, 0xef202dbe, 0x7f95be7f, 0xcfca117f, + 0x7b970b3c, 0x0db0d997, 0x8c4ce6f9, 0x7ad82088, 0xa616e289, 0xdef19bb6, + 0x3a0af214, 0x3f7d08b7, 0xb7efc2dd, 0x656b3753, 0x90ff813a, 0x8e337ae4, + 0xc674d9bb, 0x948befaa, 0x266ccae9, 0x866d3ff8, 0xfcffc64a, 0x0113e638, + 0x7fd86dfd, 0x6b5f9db0, 0xf77bef2b, 0x26f8fbbe, 0xca1f3cb3, 0xf1461ad7, + 0xa0f7e873, 0x06625a9f, 0x2e5033ea, 0x53d38b9e, 0xf7583f9e, 0x6ba0ebcf, + 0x7f3d72f5, 0xf83fbd68, 0x8ae7f43b, 0x725f7b9f, 0x52bf1d50, 0xf9d4aff7, + 0xcd2f3127, 0xe027b4a7, 0xda88baed, 0x3847a1db, 0x2193f303, 0x659376e8, + 0x91647fe6, 0x17d9b8de, 0xfee7c1ea, 0x810de8a8, 0xe486727c, 0x66593737, + 0xfbca7bd1, 0xb1661be5, 0x26e3262f, 0xaccc38e5, 0x14e7ff22, 0xd9021bd9, + 0xa28f5e11, 0xec1a77bc, 0x9ff7ce3c, 0x7e11f760, 0x0bfef608, 0xc19fe7a0, + 0x08fc21de, 0xff3e1dec, 0xc21dec04, 0xf803f02e, 0x03f053fc, 0x61dc9708, + 0xe57a829c, 0x5f62ae6a, 0x3b3dd704, 0xd3bfe302, 0x97968733, 0x9e2a598b, + 0xdd0ea5bf, 0xe9e596ae, 0x6f9c8df4, 0x4f3377bd, 0xdfc92a4d, 0x86178c26, + 0xd7b7eefb, 0x5afbedc8, 0x37bc1cf9, 0xb2e7e389, 0x473cfc34, 0xf7c69ec5, + 0x3af066d7, 0x2b8ec539, 0x1fc82af9, 0x63acaf8d, 0x29d79c9c, 0x55663cfd, + 0x0a48f7d0, 0xfde1639c, 0x5f313e48, 0x0d4c7947, 0x44a74f90, 0x172a19f2, + 0x1d385a9f, 0x772e3acc, 0xa09768c9, 0x9e82727f, 0xe361c6e2, 0x51ef90b0, + 0x394f90ae, 0x32c64b1e, 0xf3e1988f, 0xf7aca363, 0x7e3f3a3f, 0x943150d8, + 0x3ff998fd, 0x3e80ffdd, 0x8affef06, 0x8e876b7d, 0xf7db873f, 0xca2bbd40, + 0xc1f610cf, 0xb81f603a, 0xb164dcfc, 0x1d4cb78d, 0x05483bfe, 0xebe0cdae, + 0x6a83e456, 0xc5ee3094, 0xee0fa57d, 0x91fd6067, 0xcb5bfb21, 0x94225ee8, + 0x13df018f, 0x05fafb29, 0x1ba147ae, 0xa38a3e58, 0xa81994c7, 0xc590fbce, + 0x4769efc4, 0x0762b97d, 0xf645feb4, 0xf1507f13, 0x6ec51a7a, 0xc4173c0f, + 0x82730b95, 0x513339ec, 0xfd23ad9c, 0x7bbc41f2, 0x4f7830d0, 0xb7f7eca9, + 0xcbf63eb2, 0x6fffb5f9, 0x8ff65f3c, 0x73dfa3ee, 0xefcd3ff0, 0x9bc460d1, + 0x6eee0eb1, 0xcc253bf9, 0x9e5ad5af, 0xcf21ab37, 0x7d2f7bf6, 0xae01f782, + 0xaa3c4467, 0x9733e262, 0xd3fc5097, 0x7e6131a6, 0xc7e9f1be, 0x9dbca24f, + 0x7424126d, 0xd826fed9, 0x3ba7e636, 0xf43d1e8d, 0xe7e2682f, 0x45eb6b27, + 0xfcff048f, 0x696efe42, 0xfa1a33f6, 0x234d699e, 0xfe3977af, 0x6bca7af4, + 0xcf207acf, 0xc40b7186, 0xbcf1da07, 0xfe39e4be, 0xfb2512bb, 0x1efc5adc, + 0xa05aa4af, 0x97c9537c, 0xaf75e4cb, 0x6c7909d9, 0x30483dd0, 0x14bccc5e, + 0x06d4955f, 0x086b2f3f, 0xb5ef7fce, 0x94d77c0c, 0xf9c8ebc7, 0x3f62acbd, + 0xdcab8caf, 0xfac1a7c4, 0xe3c6bfeb, 0x76d8be79, 0x0353e539, 0xf8ca17c7, + 0xca2fc019, 0xfacaf6e7, 0x62e8fc95, 0x85e29b12, 0x2e313afd, 0x50efe495, + 0xc8aedf81, 0x1f485bae, 0x8c268a8f, 0x8b34b6b3, 0x7967a46e, 0x7d377eab, + 0xf4e78537, 0x3df3a446, 0xc26ff7e4, 0x273c267b, 0x83b67c84, 0xce83a6e4, + 0x6fad99e5, 0xb697dd0d, 0x4fe84de8, 0x683f479d, 0xfd06efc7, 0x57860587, + 0x7cefcaf8, 0xd78679ac, 0xcddfc199, 0x229afdf8, 0x5f006217, 0x436bef91, + 0xc33e2af8, 0x8d35f3f3, 0xdedf2823, 0xf568b4f8, 0x39785ca1, 0x17be157f, + 0x3ce8db88, 0x7c48f805, 0xdd4cfd9e, 0x07289193, 0x05fdf8fb, 0xfdf101c8, + 0x77ce2eec, 0xc443db6d, 0x2cb57f77, 0xf7fc2d07, 0xf8ea4a49, 0x17e81079, + 0xf1abc9f9, 0x5f7c6aff, 0x7c83db20, 0x3889c671, 0xe5ef778c, 0xe988adf3, + 0x9a07bf2e, 0x20bb993e, 0x7975f515, 0x26c6eee1, 0x07891980, 0xce621999, + 0x51db3a53, 0x5cb9e04b, 0x79d79e9b, 0xca045103, 0x4bfae433, 0x53dd4ce9, + 0x5e47af68, 0xfe31f143, 0xf79c0445, 0x60cf3f00, 0xb23bd09e, 0xd8cbc0fb, + 0x7e8e946f, 0x55bca58f, 0xa2e5d3e7, 0x9bf2e45f, 0x715bedaf, 0xafddc60f, + 0x433ee8ea, 0x45dff1b0, 0xe3fd6d28, 0xc84f7887, 0x416df29a, 0xff209bbf, + 0xfe2941ae, 0x37b602ae, 0xe8067a68, 0x3fa6ed80, 0x165d7bd1, 0x9e92875e, + 0x71848370, 0xcc65c6ec, 0x943e9911, 0xe764679d, 0x8729ef95, 0x3986c38d, + 0x2fe2506f, 0x12331ee6, 0x7df94cf5, 0xad0ec505, 0x3c5bbf95, 0x7529df71, + 0x96afd22c, 0x714c8eff, 0x389fd82b, 0x7922df3a, 0x38aee73b, 0xbf9782a2, + 0x468ab944, 0x0e68fab9, 0xc7db2ff6, 0x3c0683fb, 0xdf871919, 0x4f286b29, + 0x7937d01b, 0xa3df867c, 0x05f3bb40, 0x0ea6c581, 0xab6a2f61, 0x421e8f37, + 0x2e214a6e, 0xca8745c3, 0xb829b38f, 0x768377df, 0xf8f7c264, 0x9726567d, + 0x662cf72f, 0x0d5ffdc1, 0x40d8f92a, 0x947e067e, 0x19e660ea, 0xc972df29, + 0xd5ced2e7, 0x51273a26, 0xed538dfc, 0xf299b33d, 0x43972332, 0x63dfa335, + 0xb68d54e9, 0xef380d6e, 0x4e979ce8, 0x6fc59fdf, 0xdc70faf4, 0xb58205be, + 0x44e69a06, 0x5f2efcf1, 0x0bdb2f65, 0xb8a86fed, 0xf30e7ddf, 0x17fd1137, + 0xff419397, 0x93cfcfc6, 0x7f3c8d0b, 0x9adca8f3, 0xa61df489, 0xdd94eb1b, + 0x2bd52d76, 0x1d291ced, 0x677c0268, 0xefd90e71, 0x73f1df23, 0x5a65bef4, + 0xf33bf3f2, 0xae51cbec, 0x4f1b2e77, 0xd208afed, 0xe33f7863, 0x7da48e2e, + 0xcfc85cec, 0x4c2e771b, 0x5967f6a4, 0xdf1a955f, 0xd9fbe6ab, 0x3a04d8f9, + 0x39d38dff, 0xbef1b372, 0xd8c7be58, 0xc24b6a99, 0x0527d37a, 0x71bbb2fb, + 0x1a0609bc, 0xe24590ef, 0xc6cb12f7, 0xe907b63f, 0x8a9a4634, 0x7e0fdb76, + 0x7ff00def, 0x4dd86c7f, 0xf71732f5, 0xc705b99f, 0xe4057d2f, 0x37f7c60f, + 0xebbe8318, 0x66efbe57, 0xc5b4df6a, 0xb0bf40c6, 0xbcb5d791, 0xeaf6e464, + 0x3373cea0, 0xe4725fbc, 0xebb45cb3, 0xdafb07fe, 0xdaee3193, 0x243af02f, + 0xde2e5777, 0x87a89647, 0xce6faf8e, 0x4f4bf1e6, 0x8c52d44b, 0x63fa84e7, + 0xe252df54, 0xe7435dbd, 0xd9bf7254, 0x866e3cd9, 0xed1f747e, 0xdfc827de, + 0x05a6f8bb, 0x752b5bde, 0xb8fb3dcd, 0x6b34951c, 0x92e47be8, 0x51ff46fa, + 0x59d43fc4, 0xf55d7c51, 0x783ee897, 0xe8074bf6, 0x3fef02de, 0x473a08de, + 0x3b39dfe6, 0xaae63b65, 0x395ec917, 0x77f9ca9b, 0x19e2f55f, 0xd28fbdc2, + 0xf15d34ef, 0x27731d5d, 0x5f4912ab, 0x29e6b193, 0xa5f4bdb4, 0x206e23b6, + 0xbda1e961, 0x2ee7e8d1, 0x2345d474, 0x55dc61dd, 0x5e7c11da, 0x2b883dfc, + 0x7d05b5c7, 0x6ef2e69f, 0x02ebc4b9, 0x845fc8bb, 0xff80bff6, 0x6f7f3f00, + 0xd91dfcb6, 0xf25aecb5, 0x14b1f5ff, 0xa6fac157, 0x13b77e05, 0x0f4bffea, + 0x0dde7e5c, 0xbb073ded, 0x96f5c79f, 0xd515f77d, 0xf557b123, 0xdae6b754, + 0x73f93eff, 0xcd7fbde5, 0x7fa871e6, 0x583ddedf, 0x2fffea97, 0xf347159d, + 0x22997db7, 0xe36839e1, 0xf10f7437, 0xfa7cb69b, 0x8737e6de, 0xd0fc2767, + 0xb7281177, 0x75c0cc9e, 0x92bf8879, 0xac503bfc, 0xfc218655, 0x3c74de3a, + 0x1179d705, 0xba754df8, 0x72f73f12, 0xbee9cb7a, 0x8007f101, 0x8786cebe, + 0xb8ffa12f, 0x4d9cff1a, 0x61bd6f8b, 0x2b43d90a, 0xf58b95aa, 0xe87ffdd1, + 0xfb7c037b, 0xc4e3e04f, 0x86bfc11f, 0x70ff342d, 0xff88bbfc, 0x081d3e00, + 0xa6e5dfe1, 0xeb1dffbb, 0x6c535968, 0x8128f7d0, 0x08fdf374, 0x7c0915ba, + 0xdb66dffc, 0xf4bed19a, 0x0f617c1c, 0xdf2309d6, 0x2eb0966e, 0x330a72ed, + 0x7d30f7e2, 0x697f282b, 0xaed099d3, 0x407db495, 0xeb97e3fa, 0x80cfe029, + 0x06cfce7e, 0x2fc83afe, 0x55d9b6c9, 0xa2e9f46b, 0xf4efe907, 0xa2942c2c, + 0x7a19f9e9, 0x8c72e1ee, 0x2ddfc3f4, 0xdd8e7a73, 0x97c10c26, 0x9e34ecde, + 0xd1467927, 0xff6bcbbe, 0x00c0e3c2, 0x91d3097e, 0x6e28674f, 0x0a4f8e1c, + 0xeff24c1d, 0xadf00d88, 0x685feb96, 0x87f0177f, 0x7e653fee, 0xf7f0ff21, + 0xceb85cd4, 0x20cf8e68, 0x0d80f85c, 0xd5fc0f61, 0xfce3ca3a, 0x83c9f721, + 0xd79079fc, 0xa9ea855d, 0xf4e1cfbc, 0xabd3d143, 0xd2a7ffad, 0x52d92fe7, + 0x7428bc90, 0x6876f9ea, 0xcf1c6e3b, 0x9f67fef5, 0x3504da3f, 0x7f3a0f8b, + 0xf3c78c34, 0x4133a6c7, 0x7eca8fe7, 0xda73e47b, 0xf922fd9e, 0xeff2cdc7, + 0x0bda84ac, 0xd0983be5, 0xd7938ef5, 0x7f7f94eb, 0xd1a0e7a1, 0x7a718063, + 0x79216f5e, 0xd19c3676, 0x7b6a79e2, 0x9efa21fd, 0xf41fd14e, 0xf5809e13, + 0x2c78bcf7, 0xce36ec97, 0x275f0433, 0x33cf978c, 0xc79e875b, 0x682970d5, + 0x57b7529e, 0x57ab754b, 0xda82ef99, 0x778e3b76, 0x7eff83a1, 0xd0ef05e1, + 0xf1a6a9e7, 0x615cf91a, 0x2fe0873b, 0xbcfe01ed, 0x1b4db053, 0xc30c2a3f, + 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3, + 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0x0c30c30c, 0xc30c30c3, + 0x30c30c30, 0x0c30c30c, 0xc30c30c3, 0x30c30c30, 0xc1b7ff0c, 0x8dca0bff, + 0x8000e737, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131, + 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7, + 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131, + 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7, + 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131, + 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7, + 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131, + 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7, + 0x8000dcb1, 0x00008000, 0x00088b1f, 0x00000000, 0xc5edff00, 0x20000131, + 0x22b0030c, 0xb0131302, 0x14e7ff1b, 0x93c9084d, 0x26ebaf39, 0x6db6db63, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, + 0xdb6db6db, 0xb6db6db6, 0x6db6db6d, 0xdb6db6db, 0xf6db6db6, 0x10192fc7, + 0x8000dcb1, 0x00008000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0x00100000, 0x00000000, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0x00100000, 0x00000000, 0xfffffff3, 0x314fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, + 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, + 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, + 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, + 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, + 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, + 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, + 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, + 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, + 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, + 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, + 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, + 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, + 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, + 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, + 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, + 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, + 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, + 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, + 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, + 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, + 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, + 0x000a0000, 0x000700a0, 0x00028110, 0x000b8138, 0x000201f0, 0x00010210, + 0x000f0220, 0x00010310, 0x00080000, 0x00080080, 0x00028100, 0x000b8128, + 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000, 0x000800f0, + 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280, 0x00080338, + 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260, 0x00018280, + 0x000e8298, 0x00080380, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, + 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000, + 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000 +}; + +#endif /*__BNX2X_INIT_VALUES_H__*/ diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h new file mode 100644 index 0000000..8605529 --- /dev/null +++ b/drivers/net/bnx2x_reg.h @@ -0,0 +1,4394 @@ +/* bnx2x_reg.h: Broadcom Everest network driver. + * + * Copyright (c) 2007 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 + * the Free Software Foundation. + * + * The registers description starts with the regsister Access type followed + * by size in bits. For example [RW 32]. The access types are: + * R - Read only + * RC - Clear on read + * RW - Read/Write + * ST - Statistics register (clear on read) + * W - Write only + * WB - Wide bus register - the size is over 32 bits and it should be + * read/write in consecutive 32 bits accesses + * WR - Write Clear (write 1 to clear the bit) + * + */ + + +/* [R 19] Interrupt register #0 read */ +#define BRB1_REG_BRB1_INT_STS 0x6011c +/* [RW 4] Parity mask register #0 read/write */ +#define BRB1_REG_BRB1_PRTY_MASK 0x60138 +/* [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. */ +#define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200 +/* [RW 23] LL RAM data. */ +#define BRB1_REG_LL_RAM 0x61000 +/* [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 + was asserted. */ +#define BRB1_REG_NUM_OF_FULL_CYCLES_0 0x600c8 +#define BRB1_REG_NUM_OF_FULL_CYCLES_1 0x600cc +#define BRB1_REG_NUM_OF_FULL_CYCLES_2 0x600d0 +#define BRB1_REG_NUM_OF_FULL_CYCLES_3 0x600d4 +#define BRB1_REG_NUM_OF_FULL_CYCLES_4 0x600d8 +/* [ST 32] The number of cycles that the pause signal towards MAC #0 was + asserted. */ +#define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8 +#define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc +#define BRB1_REG_NUM_OF_PAUSE_CYCLES_2 0x600c0 +#define BRB1_REG_NUM_OF_PAUSE_CYCLES_3 0x600c4 +/* [RW 10] Write client 0: De-assert pause threshold. */ +#define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078 +#define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c +/* [RW 10] Write client 0: Assert pause threshold. */ +#define BRB1_REG_PAUSE_LOW_THRESHOLD_0 0x60068 +#define BRB1_REG_PAUSE_LOW_THRESHOLD_1 0x6006c +/* [RW 1] Reset the design by software. */ +#define BRB1_REG_SOFT_RESET 0x600dc +/* [R 5] Used to read the value of the XX protection CAM occupancy counter. */ +#define CCM_REG_CAM_OCCUP 0xd0188 +/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CCM_CFC_IFEN 0xd003c +/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CCM_CQM_IFEN 0xd000c +/* [RW 1] If set the Q index; received from the QM is inserted to event ID. + Otherwise 0 is inserted. */ +#define CCM_REG_CCM_CQM_USE_Q 0xd00c0 +/* [RW 11] Interrupt mask register #0 read/write */ +#define CCM_REG_CCM_INT_MASK 0xd01e4 +/* [R 11] Interrupt register #0 read */ +#define CCM_REG_CCM_INT_STS 0xd01d8 +/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS + REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). + Is used to determine the number of the AG context REG-pairs written back; + when the input message Reg1WbFlg isn't set. */ +#define CCM_REG_CCM_REG0_SZ 0xd00c4 +/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CCM_STORM0_IFEN 0xd0004 +/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CCM_STORM1_IFEN 0xd0008 +/* [RW 1] CDU AG read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define CCM_REG_CDU_AG_RD_IFEN 0xd0030 +/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input + are disregarded; all other signals are treated as usual; if 1 - normal + activity. */ +#define CCM_REG_CDU_AG_WR_IFEN 0xd002c +/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define CCM_REG_CDU_SM_RD_IFEN 0xd0038 +/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid + input is disregarded; all other signals are treated as usual; if 1 - + normal activity. */ +#define CCM_REG_CDU_SM_WR_IFEN 0xd0034 +/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 1 at start-up. */ +#define CCM_REG_CFC_INIT_CRD 0xd0204 +/* [RW 2] Auxillary counter flag Q number 1. */ +#define CCM_REG_CNT_AUX1_Q 0xd00c8 +/* [RW 2] Auxillary counter flag Q number 2. */ +#define CCM_REG_CNT_AUX2_Q 0xd00cc +/* [RW 28] The CM header value for QM request (primary). */ +#define CCM_REG_CQM_CCM_HDR_P 0xd008c +/* [RW 28] The CM header value for QM request (secondary). */ +#define CCM_REG_CQM_CCM_HDR_S 0xd0090 +/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CQM_CCM_IFEN 0xd0014 +/* [RW 6] QM output initial credit. Max credit available - 32. Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 32 at start-up. */ +#define CCM_REG_CQM_INIT_CRD 0xd020c +/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0 + stands for weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define CCM_REG_CQM_P_WEIGHT 0xd00b8 +/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_CSDM_IFEN 0xd0018 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the SDM interface is detected. */ +#define CCM_REG_CSDM_LENGTH_MIS 0xd0170 +/* [RW 28] The CM header for QM formatting in case of an error in the QM + inputs. */ +#define CCM_REG_ERR_CCM_HDR 0xd0094 +/* [RW 8] The Event ID in case the input message ErrorFlg is set. */ +#define CCM_REG_ERR_EVNT_ID 0xd0098 +/* [RW 8] FIC0 output initial credit. Max credit available - 255. Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define CCM_REG_FIC0_INIT_CRD 0xd0210 +/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define CCM_REG_FIC1_INIT_CRD 0xd0214 +/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1 + - strict priority defined by ~ccm_registers_gr_ag_pr.gr_ag_pr; + ~ccm_registers_gr_ld0_pr.gr_ld0_pr and + ~ccm_registers_gr_ld1_pr.gr_ld1_pr. Groups are according to channels and + outputs to STORM: aggregation; load FIC0; load FIC1 and store. */ +#define CCM_REG_GR_ARB_TYPE 0xd015c +/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed; that the Store channel priority is + the compliment to 4 of the rest priorities - Aggregation channel; Load + (FIC0) channel and Load (FIC1). */ +#define CCM_REG_GR_LD0_PR 0xd0164 +/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed; that the Store channel priority is + the compliment to 4 of the rest priorities - Aggregation channel; Load + (FIC0) channel and Load (FIC1). */ +#define CCM_REG_GR_LD1_PR 0xd0168 +/* [RW 2] General flags index. */ +#define CCM_REG_INV_DONE_Q 0xd0108 +/* [RW 4] The number of double REG-pairs(128 bits); loaded from the STORM + context and sent to STORM; for a specific connection type. The double + REG-pairs are used in order to align to STORM context row size of 128 + bits. The offset of these data in the STORM context is always 0. Index + _(0..15) stands for the connection type (one of 16). */ +#define CCM_REG_N_SM_CTX_LD_0 0xd004c +#define CCM_REG_N_SM_CTX_LD_1 0xd0050 +#define CCM_REG_N_SM_CTX_LD_10 0xd0074 +#define CCM_REG_N_SM_CTX_LD_11 0xd0078 +#define CCM_REG_N_SM_CTX_LD_12 0xd007c +#define CCM_REG_N_SM_CTX_LD_13 0xd0080 +#define CCM_REG_N_SM_CTX_LD_14 0xd0084 +#define CCM_REG_N_SM_CTX_LD_15 0xd0088 +#define CCM_REG_N_SM_CTX_LD_2 0xd0054 +#define CCM_REG_N_SM_CTX_LD_3 0xd0058 +#define CCM_REG_N_SM_CTX_LD_4 0xd005c +/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define CCM_REG_PBF_IFEN 0xd0028 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the pbf interface is detected. */ +#define CCM_REG_PBF_LENGTH_MIS 0xd0180 +/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define CCM_REG_PBF_WEIGHT 0xd00ac +/* [RW 6] The physical queue number of queue number 1 per port index. */ +#define CCM_REG_PHYS_QNUM1_0 0xd0134 +#define CCM_REG_PHYS_QNUM1_1 0xd0138 +/* [RW 6] The physical queue number of queue number 2 per port index. */ +#define CCM_REG_PHYS_QNUM2_0 0xd013c +#define CCM_REG_PHYS_QNUM2_1 0xd0140 +/* [RW 6] The physical queue number of queue number 3 per port index. */ +#define CCM_REG_PHYS_QNUM3_0 0xd0144 +/* [RW 6] The physical queue number of queue number 0 with QOS equal 0 port + index 0. */ +#define CCM_REG_QOS_PHYS_QNUM0_0 0xd0114 +#define CCM_REG_QOS_PHYS_QNUM0_1 0xd0118 +/* [RW 6] The physical queue number of queue number 0 with QOS equal 1 port + index 0. */ +#define CCM_REG_QOS_PHYS_QNUM1_0 0xd011c +#define CCM_REG_QOS_PHYS_QNUM1_1 0xd0120 +/* [RW 6] The physical queue number of queue number 0 with QOS equal 2 port + index 0. */ +#define CCM_REG_QOS_PHYS_QNUM2_0 0xd0124 +/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define CCM_REG_STORM_CCM_IFEN 0xd0010 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the STORM interface is detected. */ +#define CCM_REG_STORM_LENGTH_MIS 0xd016c +/* [RW 1] Input tsem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define CCM_REG_TSEM_IFEN 0xd001c +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the tsem interface is detected. */ +#define CCM_REG_TSEM_LENGTH_MIS 0xd0174 +/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define CCM_REG_TSEM_WEIGHT 0xd00a0 +/* [RW 1] Input usem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define CCM_REG_USEM_IFEN 0xd0024 +/* [RC 1] Set when message length mismatch (relative to last indication) at + the usem interface is detected. */ +#define CCM_REG_USEM_LENGTH_MIS 0xd017c +/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define CCM_REG_USEM_WEIGHT 0xd00a8 +/* [RW 1] Input xsem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define CCM_REG_XSEM_IFEN 0xd0020 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the xsem interface is detected. */ +#define CCM_REG_XSEM_LENGTH_MIS 0xd0178 +/* [RW 3] The weight of the input xsem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define CCM_REG_XSEM_WEIGHT 0xd00a4 +/* [RW 19] Indirect access to the descriptor table of the XX protection + mechanism. The fields are: [5:0] - message length; [12:6] - message + pointer; 18:13] - next pointer. */ +#define CCM_REG_XX_DESCR_TABLE 0xd0300 +/* [R 7] Used to read the value of XX protection Free counter. */ +#define CCM_REG_XX_FREE 0xd0184 +/* [RW 6] Initial value for the credit counter; responsible for fulfilling + of the Input Stage XX protection buffer by the XX protection pending + messages. Max credit available - 127. Write writes the initial credit + value; read returns the current value of the credit counter. Must be + initialized to maximum XX protected message size - 2 at start-up. */ +#define CCM_REG_XX_INIT_CRD 0xd0220 +/* [RW 7] The maximum number of pending messages; which may be stored in XX + protection. At read the ~ccm_registers_xx_free.xx_free counter is read. + At write comprises the start value of the ~ccm_registers_xx_free.xx_free + counter. */ +#define CCM_REG_XX_MSG_NUM 0xd0224 +/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */ +#define CCM_REG_XX_OVFL_EVNT_ID 0xd0044 +/* [RW 18] Indirect access to the XX table of the XX protection mechanism. + The fields are: [5:0] - tail pointer; 11:6] - Link List size; 17:12] - + header pointer. */ +#define CCM_REG_XX_TABLE 0xd0280 +#define CDU_REG_CDU_CHK_MASK0 0x101000 +#define CDU_REG_CDU_CHK_MASK1 0x101004 +#define CDU_REG_CDU_CONTROL0 0x101008 +#define CDU_REG_CDU_DEBUG 0x101010 +#define CDU_REG_CDU_GLOBAL_PARAMS 0x101020 +/* [RW 7] Interrupt mask register #0 read/write */ +#define CDU_REG_CDU_INT_MASK 0x10103c +/* [R 7] Interrupt register #0 read */ +#define CDU_REG_CDU_INT_STS 0x101030 +/* [RW 5] Parity mask register #0 read/write */ +#define CDU_REG_CDU_PRTY_MASK 0x10104c +/* [RC 32] logging of error data in case of a CDU load error: + {expected_cid[15:0]; xpected_type[2:0]; xpected_region[2:0]; ctive_error; + ype_error; ctual_active; ctual_compressed_context}; */ +#define CDU_REG_ERROR_DATA 0x101014 +/* [WB 216] L1TT ram access. each entry has the following format : + {mrege_regions[7:0]; ffset12[5:0]...offset0[5:0]; + ength12[5:0]...length0[5:0]; d12[3:0]...id0[3:0]} */ +#define CDU_REG_L1TT 0x101800 +/* [WB 24] MATT ram access. each entry has the following + format:{RegionLength[11:0]; egionOffset[11:0]} */ +#define CDU_REG_MATT 0x101100 +/* [R 1] indication the initializing the activity counter by the hardware + was done. */ +#define CFC_REG_AC_INIT_DONE 0x104078 +/* [RW 13] activity counter ram access */ +#define CFC_REG_ACTIVITY_COUNTER 0x104400 +#define CFC_REG_ACTIVITY_COUNTER_SIZE 256 +/* [R 1] indication the initializing the cams by the hardware was done. */ +#define CFC_REG_CAM_INIT_DONE 0x10407c +/* [RW 2] Interrupt mask register #0 read/write */ +#define CFC_REG_CFC_INT_MASK 0x104108 +/* [R 2] Interrupt register #0 read */ +#define CFC_REG_CFC_INT_STS 0x1040fc +/* [RC 2] Interrupt register #0 read clear */ +#define CFC_REG_CFC_INT_STS_CLR 0x104100 +/* [RW 4] Parity mask register #0 read/write */ +#define CFC_REG_CFC_PRTY_MASK 0x104118 +/* [RW 21] CID cam access (21:1 - Data; alid - 0) */ +#define CFC_REG_CID_CAM 0x104800 +#define CFC_REG_CONTROL0 0x104028 +#define CFC_REG_DEBUG0 0x104050 +/* [RW 14] indicates per error (in #cfc_registers_cfc_error_vector.cfc_error + vector) whether the cfc should be disabled upon it */ +#define CFC_REG_DISABLE_ON_ERROR 0x104044 +/* [RC 14] CFC error vector. when the CFC detects an internal error it will + set one of these bits. the bit description can be found in CFC + specifications */ +#define CFC_REG_ERROR_VECTOR 0x10403c +#define CFC_REG_INIT_REG 0x10404c +/* [RW 24] {weight_load_client7[2:0] to weight_load_client0[2:0]}. this + field allows changing the priorities of the weighted-round-robin arbiter + which selects which CFC load client should be served next */ +#define CFC_REG_LCREQ_WEIGHTS 0x104084 +/* [R 1] indication the initializing the link list by the hardware was done. */ +#define CFC_REG_LL_INIT_DONE 0x104074 +/* [R 9] Number of allocated LCIDs which are at empty state */ +#define CFC_REG_NUM_LCIDS_ALLOC 0x104020 +/* [R 9] Number of Arriving LCIDs in Link List Block */ +#define CFC_REG_NUM_LCIDS_ARRIVING 0x104004 +/* [R 9] Number of Inside LCIDs in Link List Block */ +#define CFC_REG_NUM_LCIDS_INSIDE 0x104008 +/* [R 9] Number of Leaving LCIDs in Link List Block */ +#define CFC_REG_NUM_LCIDS_LEAVING 0x104018 +/* [RW 8] The event id for aggregated interrupt 0 */ +#define CSDM_REG_AGG_INT_EVENT_0 0xc2038 +/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ +#define CSDM_REG_CFC_RSP_START_ADDR 0xc2008 +/* [RW 16] The maximum value of the competion counter #0 */ +#define CSDM_REG_CMP_COUNTER_MAX0 0xc201c +/* [RW 16] The maximum value of the competion counter #1 */ +#define CSDM_REG_CMP_COUNTER_MAX1 0xc2020 +/* [RW 16] The maximum value of the competion counter #2 */ +#define CSDM_REG_CMP_COUNTER_MAX2 0xc2024 +/* [RW 16] The maximum value of the competion counter #3 */ +#define CSDM_REG_CMP_COUNTER_MAX3 0xc2028 +/* [RW 13] The start address in the internal RAM for the completion + counters. */ +#define CSDM_REG_CMP_COUNTER_START_ADDR 0xc200c +/* [RW 32] Interrupt mask register #0 read/write */ +#define CSDM_REG_CSDM_INT_MASK_0 0xc229c +#define CSDM_REG_CSDM_INT_MASK_1 0xc22ac +/* [RW 11] Parity mask register #0 read/write */ +#define CSDM_REG_CSDM_PRTY_MASK 0xc22bc +#define CSDM_REG_ENABLE_IN1 0xc2238 +#define CSDM_REG_ENABLE_IN2 0xc223c +#define CSDM_REG_ENABLE_OUT1 0xc2240 +#define CSDM_REG_ENABLE_OUT2 0xc2244 +/* [RW 4] The initial number of messages that can be sent to the pxp control + interface without receiving any ACK. */ +#define CSDM_REG_INIT_CREDIT_PXP_CTRL 0xc24bc +/* [ST 32] The number of ACK after placement messages received */ +#define CSDM_REG_NUM_OF_ACK_AFTER_PLACE 0xc227c +/* [ST 32] The number of packet end messages received from the parser */ +#define CSDM_REG_NUM_OF_PKT_END_MSG 0xc2274 +/* [ST 32] The number of requests received from the pxp async if */ +#define CSDM_REG_NUM_OF_PXP_ASYNC_REQ 0xc2278 +/* [ST 32] The number of commands received in queue 0 */ +#define CSDM_REG_NUM_OF_Q0_CMD 0xc2248 +/* [ST 32] The number of commands received in queue 10 */ +#define CSDM_REG_NUM_OF_Q10_CMD 0xc226c +/* [ST 32] The number of commands received in queue 11 */ +#define CSDM_REG_NUM_OF_Q11_CMD 0xc2270 +/* [ST 32] The number of commands received in queue 1 */ +#define CSDM_REG_NUM_OF_Q1_CMD 0xc224c +/* [ST 32] The number of commands received in queue 3 */ +#define CSDM_REG_NUM_OF_Q3_CMD 0xc2250 +/* [ST 32] The number of commands received in queue 4 */ +#define CSDM_REG_NUM_OF_Q4_CMD 0xc2254 +/* [ST 32] The number of commands received in queue 5 */ +#define CSDM_REG_NUM_OF_Q5_CMD 0xc2258 +/* [ST 32] The number of commands received in queue 6 */ +#define CSDM_REG_NUM_OF_Q6_CMD 0xc225c +/* [ST 32] The number of commands received in queue 7 */ +#define CSDM_REG_NUM_OF_Q7_CMD 0xc2260 +/* [ST 32] The number of commands received in queue 8 */ +#define CSDM_REG_NUM_OF_Q8_CMD 0xc2264 +/* [ST 32] The number of commands received in queue 9 */ +#define CSDM_REG_NUM_OF_Q9_CMD 0xc2268 +/* [RW 13] The start address in the internal RAM for queue counters */ +#define CSDM_REG_Q_COUNTER_START_ADDR 0xc2010 +/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */ +#define CSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY 0xc2548 +/* [R 1] parser fifo empty in sdm_sync block */ +#define CSDM_REG_SYNC_PARSER_EMPTY 0xc2550 +/* [R 1] parser serial fifo empty in sdm_sync block */ +#define CSDM_REG_SYNC_SYNC_EMPTY 0xc2558 +/* [RW 32] Tick for timer counter. Applicable only when + ~csdm_registers_timer_tick_enable.timer_tick_enable =1 */ +#define CSDM_REG_TIMER_TICK 0xc2000 +/* [RW 5] The number of time_slots in the arbitration cycle */ +#define CSEM_REG_ARB_CYCLE_SIZE 0x200034 +/* [RW 3] The source that is associated with arbitration element 0. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2 */ +#define CSEM_REG_ARB_ELEMENT0 0x200020 +/* [RW 3] The source that is associated with arbitration element 1. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~csem_registers_arb_element0.arb_element0 */ +#define CSEM_REG_ARB_ELEMENT1 0x200024 +/* [RW 3] The source that is associated with arbitration element 2. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~csem_registers_arb_element0.arb_element0 + and ~csem_registers_arb_element1.arb_element1 */ +#define CSEM_REG_ARB_ELEMENT2 0x200028 +/* [RW 3] The source that is associated with arbitration element 3. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2.Could + not be equal to register ~csem_registers_arb_element0.arb_element0 and + ~csem_registers_arb_element1.arb_element1 and + ~csem_registers_arb_element2.arb_element2 */ +#define CSEM_REG_ARB_ELEMENT3 0x20002c +/* [RW 3] The source that is associated with arbitration element 4. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~csem_registers_arb_element0.arb_element0 + and ~csem_registers_arb_element1.arb_element1 and + ~csem_registers_arb_element2.arb_element2 and + ~csem_registers_arb_element3.arb_element3 */ +#define CSEM_REG_ARB_ELEMENT4 0x200030 +/* [RW 32] Interrupt mask register #0 read/write */ +#define CSEM_REG_CSEM_INT_MASK_0 0x200110 +#define CSEM_REG_CSEM_INT_MASK_1 0x200120 +/* [RW 32] Parity mask register #0 read/write */ +#define CSEM_REG_CSEM_PRTY_MASK_0 0x200130 +#define CSEM_REG_CSEM_PRTY_MASK_1 0x200140 +#define CSEM_REG_ENABLE_IN 0x2000a4 +#define CSEM_REG_ENABLE_OUT 0x2000a8 +/* [RW 32] This address space contains all registers and memories that are + placed in SEM_FAST block. The SEM_FAST registers are described in + appendix B. In order to access the SEM_FAST registers the base address + CSEM_REGISTERS_FAST_MEMORY (Offset: 0x220000) should be added to each + SEM_FAST register offset. */ +#define CSEM_REG_FAST_MEMORY 0x220000 +/* [RW 1] Disables input messages from FIC0 May be updated during run_time + by the microcode */ +#define CSEM_REG_FIC0_DISABLE 0x200224 +/* [RW 1] Disables input messages from FIC1 May be updated during run_time + by the microcode */ +#define CSEM_REG_FIC1_DISABLE 0x200234 +/* [RW 15] Interrupt table Read and write access to it is not possible in + the middle of the work */ +#define CSEM_REG_INT_TABLE 0x200400 +/* [ST 24] Statistics register. The number of messages that entered through + FIC0 */ +#define CSEM_REG_MSG_NUM_FIC0 0x200000 +/* [ST 24] Statistics register. The number of messages that entered through + FIC1 */ +#define CSEM_REG_MSG_NUM_FIC1 0x200004 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC0 */ +#define CSEM_REG_MSG_NUM_FOC0 0x200008 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC1 */ +#define CSEM_REG_MSG_NUM_FOC1 0x20000c +/* [ST 24] Statistics register. The number of messages that were sent to + FOC2 */ +#define CSEM_REG_MSG_NUM_FOC2 0x200010 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC3 */ +#define CSEM_REG_MSG_NUM_FOC3 0x200014 +/* [RW 1] Disables input messages from the passive buffer May be updated + during run_time by the microcode */ +#define CSEM_REG_PAS_DISABLE 0x20024c +/* [WB 128] Debug only. Passive buffer memory */ +#define CSEM_REG_PASSIVE_BUFFER 0x202000 +/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */ +#define CSEM_REG_PRAM 0x240000 +/* [R 16] Valid sleeping threads indication have bit per thread */ +#define CSEM_REG_SLEEP_THREADS_VALID 0x20026c +/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */ +#define CSEM_REG_SLOW_EXT_STORE_EMPTY 0x2002a0 +/* [RW 16] List of free threads . There is a bit per thread. */ +#define CSEM_REG_THREADS_LIST 0x2002e4 +/* [RW 3] The arbitration scheme of time_slot 0 */ +#define CSEM_REG_TS_0_AS 0x200038 +/* [RW 3] The arbitration scheme of time_slot 10 */ +#define CSEM_REG_TS_10_AS 0x200060 +/* [RW 3] The arbitration scheme of time_slot 11 */ +#define CSEM_REG_TS_11_AS 0x200064 +/* [RW 3] The arbitration scheme of time_slot 12 */ +#define CSEM_REG_TS_12_AS 0x200068 +/* [RW 3] The arbitration scheme of time_slot 13 */ +#define CSEM_REG_TS_13_AS 0x20006c +/* [RW 3] The arbitration scheme of time_slot 14 */ +#define CSEM_REG_TS_14_AS 0x200070 +/* [RW 3] The arbitration scheme of time_slot 15 */ +#define CSEM_REG_TS_15_AS 0x200074 +/* [RW 3] The arbitration scheme of time_slot 16 */ +#define CSEM_REG_TS_16_AS 0x200078 +/* [RW 3] The arbitration scheme of time_slot 17 */ +#define CSEM_REG_TS_17_AS 0x20007c +/* [RW 3] The arbitration scheme of time_slot 18 */ +#define CSEM_REG_TS_18_AS 0x200080 +/* [RW 3] The arbitration scheme of time_slot 1 */ +#define CSEM_REG_TS_1_AS 0x20003c +/* [RW 3] The arbitration scheme of time_slot 2 */ +#define CSEM_REG_TS_2_AS 0x200040 +/* [RW 3] The arbitration scheme of time_slot 3 */ +#define CSEM_REG_TS_3_AS 0x200044 +/* [RW 3] The arbitration scheme of time_slot 4 */ +#define CSEM_REG_TS_4_AS 0x200048 +/* [RW 3] The arbitration scheme of time_slot 5 */ +#define CSEM_REG_TS_5_AS 0x20004c +/* [RW 3] The arbitration scheme of time_slot 6 */ +#define CSEM_REG_TS_6_AS 0x200050 +/* [RW 3] The arbitration scheme of time_slot 7 */ +#define CSEM_REG_TS_7_AS 0x200054 +/* [RW 3] The arbitration scheme of time_slot 8 */ +#define CSEM_REG_TS_8_AS 0x200058 +/* [RW 3] The arbitration scheme of time_slot 9 */ +#define CSEM_REG_TS_9_AS 0x20005c +/* [RW 1] Parity mask register #0 read/write */ +#define DBG_REG_DBG_PRTY_MASK 0xc0a8 +/* [RW 2] debug only: These bits indicate the credit for PCI request type 4 + interface; MUST be configured AFTER pci_ext_buffer_strt_addr_lsb/msb are + configured */ +#define DBG_REG_PCI_REQ_CREDIT 0xc120 +/* [RW 32] Commands memory. The address to command X; row Y is to calculated + as 14*X+Y. */ +#define DMAE_REG_CMD_MEM 0x102400 +/* [RW 1] If 0 - the CRC-16c initial value is all zeroes; if 1 - the CRC-16c + initial value is all ones. */ +#define DMAE_REG_CRC16C_INIT 0x10201c +/* [RW 1] If 0 - the CRC-16 T10 initial value is all zeroes; if 1 - the + CRC-16 T10 initial value is all ones. */ +#define DMAE_REG_CRC16T10_INIT 0x102020 +/* [RW 2] Interrupt mask register #0 read/write */ +#define DMAE_REG_DMAE_INT_MASK 0x102054 +/* [RW 4] Parity mask register #0 read/write */ +#define DMAE_REG_DMAE_PRTY_MASK 0x102064 +/* [RW 1] Command 0 go. */ +#define DMAE_REG_GO_C0 0x102080 +/* [RW 1] Command 1 go. */ +#define DMAE_REG_GO_C1 0x102084 +/* [RW 1] Command 10 go. */ +#define DMAE_REG_GO_C10 0x102088 +#define DMAE_REG_GO_C10_SIZE 1 +/* [RW 1] Command 11 go. */ +#define DMAE_REG_GO_C11 0x10208c +#define DMAE_REG_GO_C11_SIZE 1 +/* [RW 1] Command 12 go. */ +#define DMAE_REG_GO_C12 0x102090 +#define DMAE_REG_GO_C12_SIZE 1 +/* [RW 1] Command 13 go. */ +#define DMAE_REG_GO_C13 0x102094 +#define DMAE_REG_GO_C13_SIZE 1 +/* [RW 1] Command 14 go. */ +#define DMAE_REG_GO_C14 0x102098 +#define DMAE_REG_GO_C14_SIZE 1 +/* [RW 1] Command 15 go. */ +#define DMAE_REG_GO_C15 0x10209c +#define DMAE_REG_GO_C15_SIZE 1 +/* [RW 1] Command 10 go. */ +#define DMAE_REG_GO_C10 0x102088 +/* [RW 1] Command 11 go. */ +#define DMAE_REG_GO_C11 0x10208c +/* [RW 1] Command 12 go. */ +#define DMAE_REG_GO_C12 0x102090 +/* [RW 1] Command 13 go. */ +#define DMAE_REG_GO_C13 0x102094 +/* [RW 1] Command 14 go. */ +#define DMAE_REG_GO_C14 0x102098 +/* [RW 1] Command 15 go. */ +#define DMAE_REG_GO_C15 0x10209c +/* [RW 1] Command 2 go. */ +#define DMAE_REG_GO_C2 0x1020a0 +/* [RW 1] Command 3 go. */ +#define DMAE_REG_GO_C3 0x1020a4 +/* [RW 1] Command 4 go. */ +#define DMAE_REG_GO_C4 0x1020a8 +/* [RW 1] Command 5 go. */ +#define DMAE_REG_GO_C5 0x1020ac +/* [RW 1] Command 6 go. */ +#define DMAE_REG_GO_C6 0x1020b0 +/* [RW 1] Command 7 go. */ +#define DMAE_REG_GO_C7 0x1020b4 +/* [RW 1] Command 8 go. */ +#define DMAE_REG_GO_C8 0x1020b8 +/* [RW 1] Command 9 go. */ +#define DMAE_REG_GO_C9 0x1020bc +/* [RW 1] DMAE GRC Interface (Target; aster) enable. If 0 - the acknowledge + input is disregarded; valid is deasserted; all other signals are treated + as usual; if 1 - normal activity. */ +#define DMAE_REG_GRC_IFEN 0x102008 +/* [RW 1] DMAE PCI Interface (Request; ead; rite) enable. If 0 - the + acknowledge input is disregarded; valid is deasserted; full is asserted; + all other signals are treated as usual; if 1 - normal activity. */ +#define DMAE_REG_PCI_IFEN 0x102004 +/* [RW 4] DMAE- PCI Request Interface initial credit. Write writes the + initial value to the credit counter; related to the address. Read returns + the current value of the counter. */ +#define DMAE_REG_PXP_REQ_INIT_CRD 0x1020c0 +/* [RW 8] Aggregation command. */ +#define DORQ_REG_AGG_CMD0 0x170060 +/* [RW 8] Aggregation command. */ +#define DORQ_REG_AGG_CMD1 0x170064 +/* [RW 8] Aggregation command. */ +#define DORQ_REG_AGG_CMD2 0x170068 +/* [RW 8] Aggregation command. */ +#define DORQ_REG_AGG_CMD3 0x17006c +/* [RW 28] UCM Header. */ +#define DORQ_REG_CMHEAD_RX 0x170050 +/* [RW 5] Interrupt mask register #0 read/write */ +#define DORQ_REG_DORQ_INT_MASK 0x170180 +/* [R 5] Interrupt register #0 read */ +#define DORQ_REG_DORQ_INT_STS 0x170174 +/* [RC 5] Interrupt register #0 read clear */ +#define DORQ_REG_DORQ_INT_STS_CLR 0x170178 +/* [RW 2] Parity mask register #0 read/write */ +#define DORQ_REG_DORQ_PRTY_MASK 0x170190 +/* [RW 8] The address to write the DPM CID to STORM. */ +#define DORQ_REG_DPM_CID_ADDR 0x170044 +/* [RW 5] The DPM mode CID extraction offset. */ +#define DORQ_REG_DPM_CID_OFST 0x170030 +/* [RW 12] The threshold of the DQ FIFO to send the almost full interrupt. */ +#define DORQ_REG_DQ_FIFO_AFULL_TH 0x17007c +/* [RW 12] The threshold of the DQ FIFO to send the full interrupt. */ +#define DORQ_REG_DQ_FIFO_FULL_TH 0x170078 +/* [R 13] Current value of the DQ FIFO fill level according to following + pointer. The range is 0 - 256 FIFO rows; where each row stands for the + doorbell. */ +#define DORQ_REG_DQ_FILL_LVLF 0x1700a4 +/* [R 1] DQ FIFO full status. Is set; when FIFO filling level is more or + equal to full threshold; reset on full clear. */ +#define DORQ_REG_DQ_FULL_ST 0x1700c0 +/* [RW 28] The value sent to CM header in the case of CFC load error. */ +#define DORQ_REG_ERR_CMHEAD 0x170058 +#define DORQ_REG_IF_EN 0x170004 +#define DORQ_REG_MODE_ACT 0x170008 +/* [RW 5] The normal mode CID extraction offset. */ +#define DORQ_REG_NORM_CID_OFST 0x17002c +/* [RW 28] TCM Header when only TCP context is loaded. */ +#define DORQ_REG_NORM_CMHEAD_TX 0x17004c +/* [RW 3] The number of simultaneous outstanding requests to Context Fetch + Interface. */ +#define DORQ_REG_OUTST_REQ 0x17003c +#define DORQ_REG_REGN 0x170038 +/* [R 4] Current value of response A counter credit. Initial credit is + configured through write to ~dorq_registers_rsp_init_crd.rsp_init_crd + register. */ +#define DORQ_REG_RSPA_CRD_CNT 0x1700ac +/* [R 4] Current value of response B counter credit. Initial credit is + configured through write to ~dorq_registers_rsp_init_crd.rsp_init_crd + register. */ +#define DORQ_REG_RSPB_CRD_CNT 0x1700b0 +/* [RW 4] The initial credit at the Doorbell Response Interface. The write + writes the same initial credit to the rspa_crd_cnt and rspb_crd_cnt. The + read reads this written value. */ +#define DORQ_REG_RSP_INIT_CRD 0x170048 +/* [RW 4] Initial activity counter value on the load request; when the + shortcut is done. */ +#define DORQ_REG_SHRT_ACT_CNT 0x170070 +/* [RW 28] TCM Header when both ULP and TCP context is loaded. */ +#define DORQ_REG_SHRT_CMHEAD 0x170054 +#define HC_CONFIG_0_REG_ATTN_BIT_EN_0 (0x1<<4) +#define HC_CONFIG_0_REG_INT_LINE_EN_0 (0x1<<3) +#define HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 (0x1<<2) +#define HC_CONFIG_0_REG_SINGLE_ISR_EN_0 (0x1<<1) +#define HC_REG_AGG_INT_0 0x108050 +#define HC_REG_AGG_INT_1 0x108054 +/* [RW 16] attention bit and attention acknowledge bits status for port 0 + and 1 according to the following address map: addr 0 - attn_bit_0; addr 1 + - attn_ack_bit_0; addr 2 - attn_bit_1; addr 3 - attn_ack_bit_1; */ +#define HC_REG_ATTN_BIT 0x108120 +/* [RW 16] attn bits status index for attn bit msg; addr 0 - function 0; + addr 1 - functin 1 */ +#define HC_REG_ATTN_IDX 0x108100 +/* [RW 32] port 0 lower 32 bits address field for attn messag. */ +#define HC_REG_ATTN_MSG0_ADDR_L 0x108018 +/* [RW 32] port 1 lower 32 bits address field for attn messag. */ +#define HC_REG_ATTN_MSG1_ADDR_L 0x108020 +/* [RW 8] status block number for attn bit msg - function 0; */ +#define HC_REG_ATTN_NUM_P0 0x108038 +/* [RW 8] status block number for attn bit msg - function 1 */ +#define HC_REG_ATTN_NUM_P1 0x10803c +#define HC_REG_CONFIG_0 0x108000 +#define HC_REG_CONFIG_1 0x108004 +/* [RW 3] Parity mask register #0 read/write */ +#define HC_REG_HC_PRTY_MASK 0x1080a0 +/* [RW 17] status block interrupt mask; one in each bit means unmask; zerow + in each bit means mask; bit 0 - default SB; bit 1 - SB_0; bit 2 - SB_1... + bit 16- SB_15; addr 0 - port 0; addr 1 - port 1 */ +#define HC_REG_INT_MASK 0x108108 +/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will + lock a change fron 0 to 1 in the corresponding attention signals that + comes from the AEU */ +#define HC_REG_LEADING_EDGE_0 0x108040 +#define HC_REG_LEADING_EDGE_1 0x108048 +/* [RW 16] all producer and consumer of port 0 according to the following + addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63; + Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons: + U/C/X/T/Attn-69/70/71/72/73 */ +#define HC_REG_P0_PROD_CONS 0x108200 +/* [RW 16] all producer and consumer of port 1according to the following + addresses; U_prod: 0-15; C_prod: 16-31; U_cons: 32-47; C_cons:48-63; + Defoult_prod: U/C/X/T/Attn-64/65/66/67/68; Defoult_cons: + U/C/X/T/Attn-69/70/71/72/73 */ +#define HC_REG_P1_PROD_CONS 0x108400 +/* [W 1] This register is write only and has 4 addresses as follow: 0 = + clear all PBA bits port 0; 1 = clear all pending interrupts request + port0; 2 = clear all PBA bits port 1; 3 = clear all pending interrupts + request port1; here is no meaning for the data in this register */ +#define HC_REG_PBA_COMMAND 0x108140 +#define HC_REG_PCI_CONFIG_0 0x108010 +#define HC_REG_PCI_CONFIG_1 0x108014 +/* [RW 24] all counters acording to the following address: LSB: 0=read; 1= + read_clear; 0-71 = HW counters (the inside order is the same as the + interrupt table in the spec); 72-219 = SW counters 1 (stops after first + consumer upd) the inside order is: 72-103 - U_non_default_p0; 104-135 + C_non_defaul_p0; 36-145 U/C/X/T/Attn_default_p0; 146-177 + U_non_default_p1; 178-209 C_non_defaul_p1; 10-219 U/C/X/T/Attn_default_p1 + ; 220-367 = SW counters 2 (stops when prod=cons) the inside order is: + 220-251 - U_non_default_p0; 252-283 C_non_defaul_p0; 84-293 + U/C/X/T/Attn_default_p0; 294-325 U_non_default_p1; 326-357 + C_non_defaul_p1; 58-367 U/C/X/T/Attn_default_p1 ; 368-515 = mailbox + counters; (the inside order of the mailbox counter is 368-431 U and C + non_default_p0; 432-441 U/C/X/T/Attn_default_p0; 442-505 U and C + non_default_p1; 506-515 U/C/X/T/Attn_default_p1) */ +#define HC_REG_STATISTIC_COUNTERS 0x109000 +/* [RW 16] port 0 attn bit condition monitoring; each bit that is set will + lock a change fron 1 to 0 in the corresponding attention signals that + comes from the AEU */ +#define HC_REG_TRAILING_EDGE_0 0x108044 +#define HC_REG_TRAILING_EDGE_1 0x10804c +#define HC_REG_UC_RAM_ADDR_0 0x108028 +#define HC_REG_UC_RAM_ADDR_1 0x108030 +/* [RW 16] ustorm address for coalesc now message */ +#define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068 +#define HC_REG_VQID_0 0x108008 +#define HC_REG_VQID_1 0x10800c +#define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 +#define MCP_REG_MCPR_NVM_ADDR 0x8640c +#define MCP_REG_MCPR_NVM_CFG4 0x8642c +#define MCP_REG_MCPR_NVM_COMMAND 0x86400 +#define MCP_REG_MCPR_NVM_READ 0x86410 +#define MCP_REG_MCPR_NVM_SW_ARB 0x86420 +#define MCP_REG_MCPR_NVM_WRITE 0x86408 +#define MCP_REG_MCPR_NVM_WRITE1 0x86428 +#define MCP_REG_MCPR_SCRATCH 0xa0000 +/* [R 32] read first 32 bit after inversion of function 0. mapped as + follows: [0] NIG attention for function0; [1] NIG attention for + function1; [2] GPIO1 mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp; + [6] GPIO1 function 1; [7] GPIO2 function 1; [8] GPIO3 function 1; [9] + GPIO4 function 1; [10] PCIE glue/PXP VPD event function0; [11] PCIE + glue/PXP VPD event function1; [12] PCIE glue/PXP Expansion ROM event0; + [13] PCIE glue/PXP Expansion ROM event1; [14] SPIO4; [15] SPIO5; [16] + MSI/X indication for mcp; [17] MSI/X indication for function 1; [18] BRB + Parity error; [19] BRB Hw interrupt; [20] PRS Parity error; [21] PRS Hw + interrupt; [22] SRC Parity error; [23] SRC Hw interrupt; [24] TSDM Parity + error; [25] TSDM Hw interrupt; [26] TCM Parity error; [27] TCM Hw + interrupt; [28] TSEMI Parity error; [29] TSEMI Hw interrupt; [30] PBF + Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_AFTER_INVERT_1_FUNC_0 0xa42c +#define MISC_REG_AEU_AFTER_INVERT_1_FUNC_1 0xa430 +/* [R 32] read first 32 bit after inversion of mcp. mapped as follows: [0] + NIG attention for function0; [1] NIG attention for function1; [2] GPIO1 + mcp; [3] GPIO2 mcp; [4] GPIO3 mcp; [5] GPIO4 mcp; [6] GPIO1 function 1; + [7] GPIO2 function 1; [8] GPIO3 function 1; [9] GPIO4 function 1; [10] + PCIE glue/PXP VPD event function0; [11] PCIE glue/PXP VPD event + function1; [12] PCIE glue/PXP Expansion ROM event0; [13] PCIE glue/PXP + Expansion ROM event1; [14] SPIO4; [15] SPIO5; [16] MSI/X indication for + mcp; [17] MSI/X indication for function 1; [18] BRB Parity error; [19] + BRB Hw interrupt; [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC + Parity error; [23] SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw + interrupt; [26] TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI + Parity error; [29] TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw + interrupt; */ +#define MISC_REG_AEU_AFTER_INVERT_1_MCP 0xa434 +/* [R 32] read second 32 bit after inversion of function 0. mapped as + follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM + Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw + interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity + error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw + interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] + NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; + [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw + interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM + Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI + Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM + Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw + interrupt; */ +#define MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 0xa438 +#define MISC_REG_AEU_AFTER_INVERT_2_FUNC_1 0xa43c +/* [R 32] read second 32 bit after inversion of mcp. mapped as follows: [0] + PBClient Parity error; [1] PBClient Hw interrupt; [2] QM Parity error; + [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw interrupt; + [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity error; [9] + XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw interrupt; [12] + DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] NIG Parity + error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; [17] Vaux + PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw interrupt; + [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM Parity error; + [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI Hw interrupt; + [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM Parity error; + [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw interrupt; */ +#define MISC_REG_AEU_AFTER_INVERT_2_MCP 0xa440 +/* [R 32] read third 32 bit after inversion of function 0. mapped as + follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP Parity + error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error; [5] + PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw + interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity + error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC) + Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16] + pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20] + MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23] + SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW + timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3 + func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General + attn1; */ +#define MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 0xa444 +#define MISC_REG_AEU_AFTER_INVERT_3_FUNC_1 0xa448 +/* [R 32] read third 32 bit after inversion of mcp. mapped as follows: [0] + CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP Parity error; [3] PXP + Hw interrupt; [4] PXPpciClockClient Parity error; [5] PXPpciClockClient + Hw interrupt; [6] CFC Parity error; [7] CFC Hw interrupt; [8] CDU Parity + error; [9] CDU Hw interrupt; [10] DMAE Parity error; [11] DMAE Hw + interrupt; [12] IGU (HC) Parity error; [13] IGU (HC) Hw interrupt; [14] + MISC Parity error; [15] MISC Hw interrupt; [16] pxp_misc_mps_attn; [17] + Flash event; [18] SMB event; [19] MCP attn0; [20] MCP attn1; [21] SW + timers attn_1 func0; [22] SW timers attn_2 func0; [23] SW timers attn_3 + func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW timers attn_1 + func1; [27] SW timers attn_2 func1; [28] SW timers attn_3 func1; [29] SW + timers attn_4 func1; [30] General attn0; [31] General attn1; */ +#define MISC_REG_AEU_AFTER_INVERT_3_MCP 0xa44c +/* [R 32] read fourth 32 bit after inversion of function 0. mapped as + follows: [0] General attn2; [1] General attn3; [2] General attn4; [3] + General attn5; [4] General attn6; [5] General attn7; [6] General attn8; + [7] General attn9; [8] General attn10; [9] General attn11; [10] General + attn12; [11] General attn13; [12] General attn14; [13] General attn15; + [14] General attn16; [15] General attn17; [16] General attn18; [17] + General attn19; [18] General attn20; [19] General attn21; [20] Main power + interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN + Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC + Latched timeout attention; [27] GRC Latched reserved access attention; + [28] MCP Latched 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_FUNC_0 0xa450 +#define MISC_REG_AEU_AFTER_INVERT_4_FUNC_1 0xa454 +/* [R 32] read fourth 32 bit after inversion of mcp. mapped as follows: [0] + General attn2; [1] General attn3; [2] General attn4; [3] General attn5; + [4] General attn6; [5] General attn7; [6] General attn8; [7] General + attn9; [8] General attn10; [9] General attn11; [10] General attn12; [11] + General attn13; [12] General attn14; [13] General attn15; [14] General + attn16; [15] General attn17; [16] General attn18; [17] General attn19; + [18] General attn20; [19] General attn21; [20] Main power interrupt; [21] + RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN Latched attn; [24] + RBCU Latched attn; [25] RBCP Latched attn; [26] GRC Latched timeout + attention; [27] GRC Latched reserved access attention; [28] MCP Latched + 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 +/* [W 11] 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 + latch; one in d5 clears GRC Latched timeout attention; one in d6 clears + GRC Latched reserved access attention; one in d7 clears Latched + rom_parity; one in d8 clears Latched ump_rx_parity; one in d9 clears + Latched ump_tx_parity; one in d10 clears Latched scpad_parity; read from + this register return zero */ +#define MISC_REG_AEU_CLR_LATCH_SIGNAL 0xa45c +/* [RW 32] first 32b for enabling the output for function 0 output0. mapped + as follows: [0] NIG attention for function0; [1] NIG attention for + function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function + 0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8] + GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event + function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP + Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14] + SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X + indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; + [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] + SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] + TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] + TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0 0xa06c +#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1 0xa07c +#define MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3 0xa09c +/* [RW 32] first 32b for enabling the output for function 1 output0. mapped + as follows: [0] NIG attention for function0; [1] NIG attention for + function1; [2] GPIO1 function 1; [3] GPIO2 function 1; [4] GPIO3 function + 1; [5] GPIO4 function 1; [6] GPIO1 function 1; [7] GPIO2 function 1; [8] + GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event + function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP + Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14] + SPIO4; [15] SPIO5; [16] MSI/X indication for function 1; [17] MSI/X + indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; + [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] + SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] + TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] + TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 0xa10c +#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1 0xa11c +#define MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3 0xa13c +/* [RW 32] first 32b for enabling the output for close the gate nig 0. + mapped as follows: [0] NIG attention for function0; [1] NIG attention for + function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function + 0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8] + GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event + function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP + Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14] + SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X + indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; + [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] + SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] + TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] + TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_ENABLE1_NIG_0 0xa0ec +#define MISC_REG_AEU_ENABLE1_NIG_1 0xa18c +/* [RW 32] first 32b for enabling the output for close the gate pxp 0. + mapped as follows: [0] NIG attention for function0; [1] NIG attention for + function1; [2] GPIO1 function 0; [3] GPIO2 function 0; [4] GPIO3 function + 0; [5] GPIO4 function 0; [6] GPIO1 function 1; [7] GPIO2 function 1; [8] + GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event + function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP + Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14] + SPIO4; [15] SPIO5; [16] MSI/X indication for function 0; [17] MSI/X + indication for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; + [20] PRS Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] + SRC Hw interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] + TCM Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] + TSEMI Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_ENABLE1_PXP_0 0xa0fc +#define MISC_REG_AEU_ENABLE1_PXP_1 0xa19c +/* [RW 32] second 32b for enabling the output for function 0 output0. mapped + as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM + Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw + interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity + error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw + interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] + NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; + [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw + interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM + Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI + Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM + Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw + interrupt; */ +#define MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0 0xa070 +#define MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1 0xa080 +/* [RW 32] second 32b for enabling the output for function 1 output0. mapped + as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; [2] QM + Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] Timers Hw + interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] XCM Parity + error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] XSEMI Hw + interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] + NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; + [17] Vaux PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw + interrupt; [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM + Parity error; [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI + Hw interrupt; [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM + Parity error; [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw + interrupt; */ +#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0 0xa110 +#define MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1 0xa120 +/* [RW 32] second 32b for enabling the output for close the gate nig 0. + mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; + [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] + Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] + XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] + XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw + interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI + core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity + error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw + interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI + Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw + interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM + Parity error; [31] CCM Hw interrupt; */ +#define MISC_REG_AEU_ENABLE2_NIG_0 0xa0f0 +#define MISC_REG_AEU_ENABLE2_NIG_1 0xa190 +/* [RW 32] second 32b for enabling the output for close the gate pxp 0. + mapped as follows: [0] PBClient Parity error; [1] PBClient Hw interrupt; + [2] QM Parity error; [3] QM Hw interrupt; [4] Timers Parity error; [5] + Timers Hw interrupt; [6] XSDM Parity error; [7] XSDM Hw interrupt; [8] + XCM Parity error; [9] XCM Hw interrupt; [10] XSEMI Parity error; [11] + XSEMI Hw interrupt; [12] DoorbellQ Parity error; [13] DoorbellQ Hw + interrupt; [14] NIG Parity error; [15] NIG Hw interrupt; [16] Vaux PCI + core Parity error; [17] Vaux PCI core Hw interrupt; [18] Debug Parity + error; [19] Debug Hw interrupt; [20] USDM Parity error; [21] USDM Hw + interrupt; [22] UCM Parity error; [23] UCM Hw interrupt; [24] USEMI + Parity error; [25] USEMI Hw interrupt; [26] UPB Parity error; [27] UPB Hw + interrupt; [28] CSDM Parity error; [29] CSDM Hw interrupt; [30] CCM + Parity error; [31] CCM Hw interrupt; */ +#define MISC_REG_AEU_ENABLE2_PXP_0 0xa100 +#define MISC_REG_AEU_ENABLE2_PXP_1 0xa1a0 +/* [RW 32] third 32b for enabling the output for function 0 output0. mapped + as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP + Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error; + [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw + interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity + error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC) + Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16] + pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20] + MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23] + SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW + timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3 + func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General + attn1; */ +#define MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0 0xa074 +#define MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1 0xa084 +/* [RW 32] third 32b for enabling the output for function 1 output0. mapped + as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] PXP + Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity error; + [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC Hw + interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE Parity + error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] IGU (HC) + Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; [16] + pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; [20] + MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; [23] + SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; [26] SW + timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers attn_3 + func1; [29] SW timers attn_4 func1; [30] General attn0; [31] General + attn1; */ +#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0 0xa114 +#define MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1 0xa124 +/* [RW 32] third 32b for enabling the output for close the gate nig 0. + mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] + PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity + error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC + Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE + Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] + IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; + [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; + [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; + [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; + [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers + attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31] + General attn1; */ +#define MISC_REG_AEU_ENABLE3_NIG_0 0xa0f4 +#define MISC_REG_AEU_ENABLE3_NIG_1 0xa194 +/* [RW 32] third 32b for enabling the output for close the gate pxp 0. + mapped as follows: [0] CSEMI Parity error; [1] CSEMI Hw interrupt; [2] + PXP Parity error; [3] PXP Hw interrupt; [4] PXPpciClockClient Parity + error; [5] PXPpciClockClient Hw interrupt; [6] CFC Parity error; [7] CFC + Hw interrupt; [8] CDU Parity error; [9] CDU Hw interrupt; [10] DMAE + Parity error; [11] DMAE Hw interrupt; [12] IGU (HC) Parity error; [13] + IGU (HC) Hw interrupt; [14] MISC Parity error; [15] MISC Hw interrupt; + [16] pxp_misc_mps_attn; [17] Flash event; [18] SMB event; [19] MCP attn0; + [20] MCP attn1; [21] SW timers attn_1 func0; [22] SW timers attn_2 func0; + [23] SW timers attn_3 func0; [24] SW timers attn_4 func0; [25] PERST; + [26] SW timers attn_1 func1; [27] SW timers attn_2 func1; [28] SW timers + attn_3 func1; [29] SW timers attn_4 func1; [30] General attn0; [31] + General attn1; */ +#define MISC_REG_AEU_ENABLE3_PXP_0 0xa104 +#define MISC_REG_AEU_ENABLE3_PXP_1 0xa1a4 +/* [RW 32] fourth 32b for enabling the output for function 0 output0.mapped + as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3] + General attn5; [4] General attn6; [5] General attn7; [6] General attn8; + [7] General attn9; [8] General attn10; [9] General attn11; [10] General + attn12; [11] General attn13; [12] General attn14; [13] General attn15; + [14] General attn16; [15] General attn17; [16] General attn18; [17] + General attn19; [18] General attn20; [19] General attn21; [20] Main power + interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN + Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC + Latched timeout attention; [27] GRC Latched reserved access attention; + [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP + Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ +#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0 0xa078 +#define MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2 0xa098 +/* [RW 32] fourth 32b for enabling the output for function 1 output0.mapped + as follows: [0] General attn2; [1] General attn3; [2] General attn4; [3] + General attn5; [4] General attn6; [5] General attn7; [6] General attn8; + [7] General attn9; [8] General attn10; [9] General attn11; [10] General + attn12; [11] General attn13; [12] General attn14; [13] General attn15; + [14] General attn16; [15] General attn17; [16] General attn18; [17] + General attn19; [18] General attn20; [19] General attn21; [20] Main power + interrupt; [21] RBCR Latched attn; [22] RBCT Latched attn; [23] RBCN + Latched attn; [24] RBCU Latched attn; [25] RBCP Latched attn; [26] GRC + Latched timeout attention; [27] GRC Latched reserved access attention; + [28] MCP Latched rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP + Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ +#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0 0xa118 +#define MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2 0xa138 +/* [RW 32] fourth 32b for enabling the output for close the gate nig + 0.mapped as follows: [0] General attn2; [1] General attn3; [2] General + attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6] + General attn8; [7] General attn9; [8] General attn10; [9] General attn11; + [10] General attn12; [11] General attn13; [12] General attn14; [13] + General attn15; [14] General attn16; [15] General attn17; [16] General + attn18; [17] General attn19; [18] General attn20; [19] General attn21; + [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched + attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched + attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved + access attention; [28] MCP Latched rom_parity; [29] MCP Latched + ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched + scpad_parity; */ +#define MISC_REG_AEU_ENABLE4_NIG_0 0xa0f8 +#define MISC_REG_AEU_ENABLE4_NIG_1 0xa198 +/* [RW 32] fourth 32b for enabling the output for close the gate pxp + 0.mapped as follows: [0] General attn2; [1] General attn3; [2] General + attn4; [3] General attn5; [4] General attn6; [5] General attn7; [6] + General attn8; [7] General attn9; [8] General attn10; [9] General attn11; + [10] General attn12; [11] General attn13; [12] General attn14; [13] + General attn15; [14] General attn16; [15] General attn17; [16] General + attn18; [17] General attn19; [18] General attn20; [19] General attn21; + [20] Main power interrupt; [21] RBCR Latched attn; [22] RBCT Latched + attn; [23] RBCN Latched attn; [24] RBCU Latched attn; [25] RBCP Latched + attn; [26] GRC Latched timeout attention; [27] GRC Latched reserved + access attention; [28] MCP Latched rom_parity; [29] MCP Latched + ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched + scpad_parity; */ +#define MISC_REG_AEU_ENABLE4_PXP_0 0xa108 +#define MISC_REG_AEU_ENABLE4_PXP_1 0xa1a8 +/* [RW 1] set/clr general attention 0; this will set/clr bit 94 in the aeu + 128 bit vector */ +#define MISC_REG_AEU_GENERAL_ATTN_0 0xa000 +#define MISC_REG_AEU_GENERAL_ATTN_1 0xa004 +#define MISC_REG_AEU_GENERAL_ATTN_10 0xa028 +#define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c +#define MISC_REG_AEU_GENERAL_ATTN_12 0xa030 +#define MISC_REG_AEU_GENERAL_ATTN_13 0xa034 +#define MISC_REG_AEU_GENERAL_ATTN_14 0xa038 +#define MISC_REG_AEU_GENERAL_ATTN_15 0xa03c +#define MISC_REG_AEU_GENERAL_ATTN_16 0xa040 +#define MISC_REG_AEU_GENERAL_ATTN_17 0xa044 +#define MISC_REG_AEU_GENERAL_ATTN_18 0xa048 +#define MISC_REG_AEU_GENERAL_ATTN_19 0xa04c +#define MISC_REG_AEU_GENERAL_ATTN_11 0xa02c +#define MISC_REG_AEU_GENERAL_ATTN_2 0xa008 +#define MISC_REG_AEU_GENERAL_ATTN_20 0xa050 +#define MISC_REG_AEU_GENERAL_ATTN_21 0xa054 +#define MISC_REG_AEU_GENERAL_ATTN_3 0xa00c +#define MISC_REG_AEU_GENERAL_ATTN_4 0xa010 +#define MISC_REG_AEU_GENERAL_ATTN_5 0xa014 +#define MISC_REG_AEU_GENERAL_ATTN_6 0xa018 +/* [RW 32] first 32b for inverting the input for function 0; for each bit: + 0= do not invert; 1= invert; mapped as follows: [0] NIG attention for + function0; [1] NIG attention for function1; [2] GPIO1 mcp; [3] GPIO2 mcp; + [4] GPIO3 mcp; [5] GPIO4 mcp; [6] GPIO1 function 1; [7] GPIO2 function 1; + [8] GPIO3 function 1; [9] GPIO4 function 1; [10] PCIE glue/PXP VPD event + function0; [11] PCIE glue/PXP VPD event function1; [12] PCIE glue/PXP + Expansion ROM event0; [13] PCIE glue/PXP Expansion ROM event1; [14] + SPIO4; [15] SPIO5; [16] MSI/X indication for mcp; [17] MSI/X indication + for function 1; [18] BRB Parity error; [19] BRB Hw interrupt; [20] PRS + Parity error; [21] PRS Hw interrupt; [22] SRC Parity error; [23] SRC Hw + interrupt; [24] TSDM Parity error; [25] TSDM Hw interrupt; [26] TCM + Parity error; [27] TCM Hw interrupt; [28] TSEMI Parity error; [29] TSEMI + Hw interrupt; [30] PBF Parity error; [31] PBF Hw interrupt; */ +#define MISC_REG_AEU_INVERTER_1_FUNC_0 0xa22c +#define MISC_REG_AEU_INVERTER_1_FUNC_1 0xa23c +/* [RW 32] second 32b for inverting the input for function 0; for each bit: + 0= do not invert; 1= invert. mapped as follows: [0] PBClient Parity + error; [1] PBClient Hw interrupt; [2] QM Parity error; [3] QM Hw + interrupt; [4] Timers Parity error; [5] Timers Hw interrupt; [6] XSDM + Parity error; [7] XSDM Hw interrupt; [8] XCM Parity error; [9] XCM Hw + interrupt; [10] XSEMI Parity error; [11] XSEMI Hw interrupt; [12] + DoorbellQ Parity error; [13] DoorbellQ Hw interrupt; [14] NIG Parity + error; [15] NIG Hw interrupt; [16] Vaux PCI core Parity error; [17] Vaux + PCI core Hw interrupt; [18] Debug Parity error; [19] Debug Hw interrupt; + [20] USDM Parity error; [21] USDM Hw interrupt; [22] UCM Parity error; + [23] UCM Hw interrupt; [24] USEMI Parity error; [25] USEMI Hw interrupt; + [26] UPB Parity error; [27] UPB Hw interrupt; [28] CSDM Parity error; + [29] CSDM Hw interrupt; [30] CCM Parity error; [31] CCM Hw interrupt; */ +#define MISC_REG_AEU_INVERTER_2_FUNC_0 0xa230 +#define MISC_REG_AEU_INVERTER_2_FUNC_1 0xa240 +/* [RW 10] [7:0] = mask 8 attention output signals toward IGU function0; + [9:8] = mask close the gates signals of function 0 toward PXP [8] and NIG + [9]. Zero = mask; one = unmask */ +#define MISC_REG_AEU_MASK_ATTN_FUNC_0 0xa060 +#define MISC_REG_AEU_MASK_ATTN_FUNC_1 0xa064 +/* [R 4] This field indicates the type of the device. '0' - 2 Ports; '1' - 1 + Port. */ +#define MISC_REG_BOND_ID 0xa400 +/* [R 8] These bits indicate the metal revision of the chip. This value + starts at 0x00 for each all-layer tape-out and increments by one for each + tape-out. */ +#define MISC_REG_CHIP_METAL 0xa404 +/* [R 16] These bits indicate the part number for the chip. */ +#define MISC_REG_CHIP_NUM 0xa408 +/* [R 4] These bits indicate the base revision of the chip. This value + starts at 0x0 for the A0 tape-out and increments by one for each + all-layer tape-out. */ +#define MISC_REG_CHIP_REV 0xa40c +/* [RW 1] Setting this bit enables a timer in the GRC block to timeout any + access that does not finish within + ~misc_registers_grc_timout_val.grc_timeout_val cycles. When this bit is + cleared; this timeout is disabled. If this timeout occurs; the GRC shall + assert it attention output. */ +#define MISC_REG_GRC_TIMEOUT_EN 0xa280 +/* [RW 28] 28 LSB of LCPLL first register; reset val = 521. inside order of + the bits is: [2:0] OAC reset value 001) CML output buffer bias control; + 111 for +40%; 011 for +20%; 001 for 0%; 000 for -20%. [5:3] Icp_ctrl + (reset value 001) Charge pump current control; 111 for 720u; 011 for + 600u; 001 for 480u and 000 for 360u. [7:6] Bias_ctrl (reset value 00) + Global bias control; When bit 7 is high bias current will be 10 0gh; When + bit 6 is high bias will be 100w; Valid values are 00; 10; 01. [10:8] + Pll_observe (reset value 010) Bits to control observability. bit 10 is + for test bias; bit 9 is for test CK; bit 8 is test Vc. [12:11] Vth_ctrl + (reset value 00) Comparator threshold control. 00 for 0.6V; 01 for 0.54V + and 10 for 0.66V. [13] pllSeqStart (reset value 0) Enables VCO tuning + sequencer: 1= sequencer disabled; 0= sequencer enabled (inverted + internally). [14] reserved (reset value 0) Reset for VCO sequencer is + connected to RESET input directly. [15] capRetry_en (reset value 0) + enable retry on cap search failure (inverted). [16] freqMonitor_e (reset + value 0) bit to continuously monitor vco freq (inverted). [17] + freqDetRestart_en (reset value 0) bit to enable restart when not freq + locked (inverted). [18] freqDetRetry_en (reset value 0) bit to enable + retry on freq det failure(inverted). [19] pllForceFdone_en (reset value + 0) bit to enable pllForceFdone & pllForceFpass into pllSeq. [20] + pllForceFdone (reset value 0) bit to force freqDone. [21] pllForceFpass + (reset value 0) bit to force freqPass. [22] pllForceDone_en (reset value + 0) bit to enable pllForceCapDone. [23] pllForceCapDone (reset value 0) + bit to force capDone. [24] pllForceCapPass_en (reset value 0) bit to + enable pllForceCapPass. [25] pllForceCapPass (reset value 0) bit to force + capPass. [26] capRestart (reset value 0) bit to force cap sequencer to + restart. [27] capSelectM_en (reset value 0) bit to enable cap select + register bits. */ +#define MISC_REG_LCPLL_CTRL_1 0xa2a4 +#define MISC_REG_LCPLL_CTRL_REG_2 0xa2a8 +/* [RW 4] Interrupt mask register #0 read/write */ +#define MISC_REG_MISC_INT_MASK 0xa388 +/* [RW 1] Parity mask register #0 read/write */ +#define MISC_REG_MISC_PRTY_MASK 0xa398 +/* [RW 32] 32 LSB of storm PLL first register; reset val = 0x 071d2911. + inside order of the bits is: [0] P1 divider[0] (reset value 1); [1] P1 + divider[1] (reset value 0); [2] P1 divider[2] (reset value 0); [3] P1 + divider[3] (reset value 0); [4] P2 divider[0] (reset value 1); [5] P2 + divider[1] (reset value 0); [6] P2 divider[2] (reset value 0); [7] P2 + divider[3] (reset value 0); [8] ph_det_dis (reset value 1); [9] + freq_det_dis (reset value 0); [10] Icpx[0] (reset value 0); [11] Icpx[1] + (reset value 1); [12] Icpx[2] (reset value 0); [13] Icpx[3] (reset value + 1); [14] Icpx[4] (reset value 0); [15] Icpx[5] (reset value 0); [16] + Rx[0] (reset value 1); [17] Rx[1] (reset value 0); [18] vc_en (reset + value 1); [19] vco_rng[0] (reset value 1); [20] vco_rng[1] (reset value + 1); [21] Kvco_xf[0] (reset value 0); [22] Kvco_xf[1] (reset value 0); + [23] Kvco_xf[2] (reset value 0); [24] Kvco_xs[0] (reset value 1); [25] + Kvco_xs[1] (reset value 1); [26] Kvco_xs[2] (reset value 1); [27] + testd_en (reset value 0); [28] testd_sel[0] (reset value 0); [29] + testd_sel[1] (reset value 0); [30] testd_sel[2] (reset value 0); [31] + testa_en (reset value 0); */ +#define MISC_REG_PLL_STORM_CTRL_1 0xa294 +#define MISC_REG_PLL_STORM_CTRL_2 0xa298 +#define MISC_REG_PLL_STORM_CTRL_3 0xa29c +#define MISC_REG_PLL_STORM_CTRL_4 0xa2a0 +/* [RW 32] reset reg#1; 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 + to all the bits that have the value of one in the data written (bits that + have the value of zero will not be change) ; addr 2-clear - zero will be + written to all the bits that have the value of one in the data written + (bits that have the value of zero will not be change); addr 3-ignore; + read ignore from all addr except addr 00; inside order of the bits is: + [0] rst_brb1; [1] rst_prs; [2] rst_src; [3] rst_tsdm; [4] rst_tsem; [5] + rst_tcm; [6] rst_rbcr; [7] rst_nig; [8] rst_usdm; [9] rst_ucm; [10] + rst_usem; [11] rst_upb; [12] rst_ccm; [13] rst_csem; [14] rst_csdm; [15] + rst_rbcu; [16] rst_pbf; [17] rst_qm; [18] rst_tm; [19] rst_dorq; [20] + rst_xcm; [21] rst_xsdm; [22] rst_xsem; [23] rst_rbct; [24] rst_cdu; [25] + rst_cfc; [26] rst_pxp; [27] rst_pxpv; [28] rst_rbcp; [29] rst_hc; [30] + rst_dmae; [31] rst_semi_rtc; */ +#define MISC_REG_RESET_REG_1 0xa580 +#define MISC_REG_RESET_REG_2 0xa590 +/* [RW 20] 20 bit GRC address where the scratch-pad of the MCP that is + shared with the driver resides */ +#define MISC_REG_SHARED_MEM_ADDR 0xa2b4 +#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT (0x1<<0) +#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS (0x1<<9) +#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G (0x1<<15) +#define NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS (0xf<<18) +/* [RW 1] Input enable for RX_BMAC0 IF */ +#define NIG_REG_BMAC0_IN_EN 0x100ac +/* [RW 1] output enable for TX_BMAC0 IF */ +#define NIG_REG_BMAC0_OUT_EN 0x100e0 +/* [RW 1] output enable for TX BMAC pause port 0 IF */ +#define NIG_REG_BMAC0_PAUSE_OUT_EN 0x10110 +/* [RW 1] output enable for RX_BMAC0_REGS IF */ +#define NIG_REG_BMAC0_REGS_OUT_EN 0x100e8 +/* [RW 1] output enable for RX BRB1 port0 IF */ +#define NIG_REG_BRB0_OUT_EN 0x100f8 +/* [RW 1] Input enable for TX BRB1 pause port 0 IF */ +#define NIG_REG_BRB0_PAUSE_IN_EN 0x100c4 +/* [RW 1] output enable for RX BRB1 port1 IF */ +#define NIG_REG_BRB1_OUT_EN 0x100fc +/* [RW 1] Input enable for TX BRB1 pause port 1 IF */ +#define NIG_REG_BRB1_PAUSE_IN_EN 0x100c8 +/* [RW 1] output enable for RX BRB1 LP IF */ +#define NIG_REG_BRB_LB_OUT_EN 0x10100 +/* [WB_W 72] Debug packet to LP from RBC; Data spelling:[63:0] data; 64] + error; [67:65]eop_bvalid; [68]eop; [69]sop; [70]port_id; 71]flush */ +#define NIG_REG_DEBUG_PACKET_LB 0x10800 +/* [RW 1] Input enable for TX Debug packet */ +#define NIG_REG_EGRESS_DEBUG_IN_EN 0x100dc +/* [RW 1] If 1 - egress drain mode for port0 is active. In this mode all + packets from PBFare not forwarded to the MAC and just deleted from FIFO. + First packet may be deleted from the middle. And last packet will be + always deleted till the end. */ +#define NIG_REG_EGRESS_DRAIN0_MODE 0x10060 +/* [RW 1] Output enable to EMAC0 */ +#define NIG_REG_EGRESS_EMAC0_OUT_EN 0x10120 +/* [RW 1] MAC configuration for packets of port0. If 1 - all packet outputs + to emac for port0; other way to bmac for port0 */ +#define NIG_REG_EGRESS_EMAC0_PORT 0x10058 +/* [RW 1] Input enable for TX PBF user packet port0 IF */ +#define NIG_REG_EGRESS_PBF0_IN_EN 0x100cc +/* [RW 1] Input enable for TX PBF user packet port1 IF */ +#define NIG_REG_EGRESS_PBF1_IN_EN 0x100d0 +/* [RW 1] Input enable for RX_EMAC0 IF */ +#define NIG_REG_EMAC0_IN_EN 0x100a4 +/* [RW 1] output enable for TX EMAC pause port 0 IF */ +#define NIG_REG_EMAC0_PAUSE_OUT_EN 0x10118 +/* [R 1] status from emac0. This bit is set when MDINT from either the + EXT_MDINT pin or from the Copper PHY is driven low. This condition must + be cleared in the attached PHY device that is driving the MINT pin. */ +#define NIG_REG_EMAC0_STATUS_MISC_MI_INT 0x10494 +/* [WB 48] This address space contains BMAC0 registers. The BMAC registers + are described in appendix A. In order to access the BMAC0 registers; the + base address; NIG_REGISTERS_INGRESS_BMAC0_MEM; Offset: 0x10c00; should be + added to each BMAC register offset */ +#define NIG_REG_INGRESS_BMAC0_MEM 0x10c00 +/* [WB 48] This address space contains BMAC1 registers. The BMAC registers + are described in appendix A. In order to access the BMAC0 registers; the + base address; NIG_REGISTERS_INGRESS_BMAC1_MEM; Offset: 0x11000; should be + added to each BMAC register offset */ +#define NIG_REG_INGRESS_BMAC1_MEM 0x11000 +/* [R 1] FIFO empty in EOP descriptor FIFO of LP in NIG_RX_EOP */ +#define NIG_REG_INGRESS_EOP_LB_EMPTY 0x104e0 +/* [RW 17] Debug only. RX_EOP_DSCR_lb_FIFO in NIG_RX_EOP. Data + packet_length[13:0]; mac_error[14]; trunc_error[15]; parity[16] */ +#define NIG_REG_INGRESS_EOP_LB_FIFO 0x104e4 +/* [RW 1] led 10g for port 0 */ +#define NIG_REG_LED_10G_P0 0x10320 +/* [RW 1] Port0: This bit is set to enable the use of the + ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 field + defined below. If this bit is cleared; then the blink rate will be about + 8Hz. */ +#define NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 0x10318 +/* [RW 12] Port0: Specifies the period of each blink cycle (on + off) for + Traffic LED in milliseconds. Must be a non-zero value. This 12-bit field + is reset to 0x080; giving a default blink period of approximately 8Hz. */ +#define NIG_REG_LED_CONTROL_BLINK_RATE_P0 0x10310 +/* [RW 1] Port0: If set along with the + nig_registers_led_control_override_traffic_p0.led_control_override_traffic_p0 + bit and ~nig_registers_led_control_traffic_p0.led_control_traffic_p0 LED + bit; the Traffic LED will blink with the blink rate specified in + ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 and + ~nig_registers_led_control_blink_rate_ena_p0.led_control_blink_rate_ena_p0 + fields. */ +#define NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 0x10308 +/* [RW 1] Port0: If set overrides hardware control of the Traffic LED. The + Traffic LED will then be controlled via bit ~nig_registers_ + led_control_traffic_p0.led_control_traffic_p0 and bit + ~nig_registers_led_control_blink_traffic_p0.led_control_blink_traffic_p0 */ +#define NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 0x102f8 +/* [RW 1] Port0: If set along with the led_control_override_trafic_p0 bit; + turns on the Traffic LED. If the led_control_blink_traffic_p0 bit is also + set; the LED will blink with blink rate specified in + ~nig_registers_led_control_blink_rate_p0.led_control_blink_rate_p0 and + ~nig_regsters_led_control_blink_rate_ena_p0.led_control_blink_rate_ena_p0 + fields. */ +#define NIG_REG_LED_CONTROL_TRAFFIC_P0 0x10300 +/* [RW 4] led mode for port0: 0 MAC; 1-3 PHY1; 4 MAC2; 5-7 PHY4; 8-MAC3; + 9-11PHY7; 12 MAC4; 13-15 PHY10; */ +#define NIG_REG_LED_MODE_P0 0x102f0 +#define NIG_REG_LLH0_BRB1_DRV_MASK 0x10244 +/* [RW 1] send to BRB1 if no match on any of RMP rules. */ +#define NIG_REG_LLH0_BRB1_NOT_MCP 0x1025c +/* [RW 32] cm header for llh0 */ +#define NIG_REG_LLH0_CM_HEADER 0x1007c +#define NIG_REG_LLH0_ERROR_MASK 0x1008c +/* [RW 8] event id for llh0 */ +#define NIG_REG_LLH0_EVENT_ID 0x10084 +/* [RW 8] init credit counter for port0 in LLH */ +#define NIG_REG_LLH0_XCM_INIT_CREDIT 0x10554 +#define NIG_REG_LLH0_XCM_MASK 0x10130 +/* [RW 1] send to BRB1 if no match on any of RMP rules. */ +#define NIG_REG_LLH1_BRB1_NOT_MCP 0x102dc +/* [RW 32] cm header for llh1 */ +#define NIG_REG_LLH1_CM_HEADER 0x10080 +#define NIG_REG_LLH1_ERROR_MASK 0x10090 +/* [RW 8] event id for llh1 */ +#define NIG_REG_LLH1_EVENT_ID 0x10088 +/* [RW 8] init credit counter for port1 in LLH */ +#define NIG_REG_LLH1_XCM_INIT_CREDIT 0x10564 +#define NIG_REG_LLH1_XCM_MASK 0x10134 +#define NIG_REG_MASK_INTERRUPT_PORT0 0x10330 +#define NIG_REG_MASK_INTERRUPT_PORT1 0x10334 +/* [RW 1] Output signal from NIG to EMAC0. When set enables the EMAC0 block. */ +#define NIG_REG_NIG_EMAC0_EN 0x1003c +/* [RW 1] Output signal from NIG to TX_EMAC0. When set indicates to the + EMAC0 to strip the CRC from the ingress packets. */ +#define NIG_REG_NIG_INGRESS_EMAC0_NO_CRC 0x10044 +/* [RW 1] Input enable for RX PBF LP IF */ +#define NIG_REG_PBF_LB_IN_EN 0x100b4 +/* [RW 1] output enable for RX parser descriptor IF */ +#define NIG_REG_PRS_EOP_OUT_EN 0x10104 +/* [RW 1] Input enable for RX parser request IF */ +#define NIG_REG_PRS_REQ_IN_EN 0x100b8 +/* [RW 5] control to serdes - CL22 PHY_ADD and CL45 PRTAD */ +#define NIG_REG_SERDES0_CTRL_PHY_ADDR 0x10374 +/* [R 1] status from serdes0 that inputs to interrupt logic of link status */ +#define NIG_REG_SERDES0_STATUS_LINK_STATUS 0x10578 +/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure + for port0 */ +#define NIG_REG_STAT0_BRB_DISCARD 0x105f0 +/* [R 32] Rx statistics : In user packets discarded due to BRB backpressure + for port1 */ +#define NIG_REG_STAT1_BRB_DISCARD 0x10628 +/* [WB_R 64] Rx statistics : User octets received for LP */ +#define NIG_REG_STAT2_BRB_OCTET 0x107e0 +#define NIG_REG_STATUS_INTERRUPT_PORT0 0x10328 +#define NIG_REG_STATUS_INTERRUPT_PORT1 0x1032c +/* [RW 1] output enable for RX_XCM0 IF */ +#define NIG_REG_XCM0_OUT_EN 0x100f0 +/* [RW 1] output enable for RX_XCM1 IF */ +#define NIG_REG_XCM1_OUT_EN 0x100f4 +/* [RW 5] control to xgxs - CL45 DEVAD */ +#define NIG_REG_XGXS0_CTRL_MD_DEVAD 0x1033c +/* [RW 5] control to xgxs - CL22 PHY_ADD and CL45 PRTAD */ +#define NIG_REG_XGXS0_CTRL_PHY_ADDR 0x10340 +/* [R 1] status from xgxs0 that inputs to interrupt logic of link10g. */ +#define NIG_REG_XGXS0_STATUS_LINK10G 0x10680 +/* [R 4] status from xgxs0 that inputs to interrupt logic of link status */ +#define NIG_REG_XGXS0_STATUS_LINK_STATUS 0x10684 +/* [RW 2] selection for XGXS lane of port 0 in NIG_MUX block */ +#define NIG_REG_XGXS_LANE_SEL_P0 0x102e8 +/* [RW 1] selection for port0 for NIG_MUX block : 0 = SerDes; 1 = XGXS */ +#define NIG_REG_XGXS_SERDES0_MODE_SEL 0x102e0 +#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS (0x1<<9) +#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G (0x1<<15) +#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS (0xf<<18) +#define NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE 18 +/* [RW 1] Disable processing further tasks from port 0 (after ending the + current task in process). */ +#define PBF_REG_DISABLE_NEW_TASK_PROC_P0 0x14005c +/* [RW 1] Disable processing further tasks from port 1 (after ending the + current task in process). */ +#define PBF_REG_DISABLE_NEW_TASK_PROC_P1 0x140060 +/* [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_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 + the configuration of the block has ended. */ +#define PBF_REG_INIT 0x140000 +/* [RW 1] Init bit for port 0. When set the initial credit of port 0 is + copied to the credit register. Should be set and then reset after the + configuration of the port has ended. */ +#define PBF_REG_INIT_P0 0x140004 +/* [RW 1] Init bit for port 1. When set the initial credit of port 1 is + copied to the credit register. Should be set and then reset after the + configuration of the port has ended. */ +#define PBF_REG_INIT_P1 0x140008 +/* [RW 1] Init bit for port 4. When set the initial credit of port 4 is + copied to the credit register. Should be set and then reset after the + configuration of the port has ended. */ +#define PBF_REG_INIT_P4 0x14000c +/* [RW 1] Enable for mac interface 0. */ +#define PBF_REG_MAC_IF0_ENABLE 0x140030 +/* [RW 1] Enable for mac interface 1. */ +#define PBF_REG_MAC_IF1_ENABLE 0x140034 +/* [RW 1] Enable for the loopback interface. */ +#define PBF_REG_MAC_LB_ENABLE 0x140040 +/* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause + not suppoterd. */ +#define PBF_REG_P0_ARB_THRSH 0x1400e4 +/* [R 11] Current credit for port 0 in the tx port buffers in 16 byte lines. */ +#define PBF_REG_P0_CREDIT 0x140200 +/* [RW 11] Initial credit for port 0 in the tx port buffers in 16 byte + lines. */ +#define PBF_REG_P0_INIT_CRD 0x1400d0 +/* [RW 1] Indication that pause is enabled for port 0. */ +#define PBF_REG_P0_PAUSE_ENABLE 0x140014 +/* [R 8] Number of tasks in port 0 task queue. */ +#define PBF_REG_P0_TASK_CNT 0x140204 +/* [R 11] Current credit for port 1 in the tx port buffers in 16 byte lines. */ +#define PBF_REG_P1_CREDIT 0x140208 +/* [RW 11] Initial credit for port 1 in the tx port buffers in 16 byte + lines. */ +#define PBF_REG_P1_INIT_CRD 0x1400d4 +/* [R 8] Number of tasks in port 1 task queue. */ +#define PBF_REG_P1_TASK_CNT 0x14020c +/* [R 11] Current credit for port 4 in the tx port buffers in 16 byte lines. */ +#define PBF_REG_P4_CREDIT 0x140210 +/* [RW 11] Initial credit for port 4 in the tx port buffers in 16 byte + lines. */ +#define PBF_REG_P4_INIT_CRD 0x1400e0 +/* [R 8] Number of tasks in port 4 task queue. */ +#define PBF_REG_P4_TASK_CNT 0x140214 +/* [RW 5] Interrupt mask register #0 read/write */ +#define PBF_REG_PBF_INT_MASK 0x1401d4 +/* [R 5] Interrupt register #0 read */ +#define PBF_REG_PBF_INT_STS 0x1401c8 +#define PB_REG_CONTROL 0 +/* [RW 2] Interrupt mask register #0 read/write */ +#define PB_REG_PB_INT_MASK 0x28 +/* [R 2] Interrupt register #0 read */ +#define PB_REG_PB_INT_STS 0x1c +/* [RW 4] Parity mask register #0 read/write */ +#define PB_REG_PB_PRTY_MASK 0x38 +#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 +/* [R 8] debug only: CFC search request current credit. Transaction based. */ +#define PRS_REG_CFC_SEARCH_CURRENT_CREDIT 0x40168 +/* [RW 6] The initial credit for the search message to the CFC interface. + Credit is transaction based. */ +#define PRS_REG_CFC_SEARCH_INITIAL_CREDIT 0x4011c +/* [RW 24] CID for port 0 if no match */ +#define PRS_REG_CID_PORT_0 0x400fc +#define PRS_REG_CID_PORT_1 0x40100 +/* [RW 32] The CM header for flush message where 'load existed' bit in CFC + load response is reset and packet type is 0. Used in packet start message + to TCM. */ +#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0 0x400dc +#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1 0x400e0 +#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2 0x400e4 +#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3 0x400e8 +#define PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4 0x400ec +/* [RW 32] The CM header for flush message where 'load existed' bit in CFC + load response is set and packet type is 0. Used in packet start message + to TCM. */ +#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0 0x400bc +#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1 0x400c0 +#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2 0x400c4 +#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3 0x400c8 +#define PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4 0x400cc +/* [RW 32] The CM header for a match and packet type 1 for loopback port. + Used in packet start message to TCM. */ +#define PRS_REG_CM_HDR_LOOPBACK_TYPE_1 0x4009c +#define PRS_REG_CM_HDR_LOOPBACK_TYPE_2 0x400a0 +#define PRS_REG_CM_HDR_LOOPBACK_TYPE_3 0x400a4 +#define PRS_REG_CM_HDR_LOOPBACK_TYPE_4 0x400a8 +/* [RW 32] The CM header for a match and packet type 0. Used in packet start + message to TCM. */ +#define PRS_REG_CM_HDR_TYPE_0 0x40078 +#define PRS_REG_CM_HDR_TYPE_1 0x4007c +#define PRS_REG_CM_HDR_TYPE_2 0x40080 +#define PRS_REG_CM_HDR_TYPE_3 0x40084 +#define PRS_REG_CM_HDR_TYPE_4 0x40088 +/* [RW 32] The CM header in case there was not a match on the connection */ +#define PRS_REG_CM_NO_MATCH_HDR 0x400b8 +/* [RW 8] The 8-bit event ID for a match and packet type 1. Used in packet + start message to TCM. */ +#define PRS_REG_EVENT_ID_1 0x40054 +#define PRS_REG_EVENT_ID_2 0x40058 +#define PRS_REG_EVENT_ID_3 0x4005c +/* [RW 8] Context region for flush packet with packet type 0. Used in CFC + load request message. */ +#define PRS_REG_FLUSH_REGIONS_TYPE_0 0x40004 +#define PRS_REG_FLUSH_REGIONS_TYPE_1 0x40008 +#define PRS_REG_FLUSH_REGIONS_TYPE_2 0x4000c +#define PRS_REG_FLUSH_REGIONS_TYPE_3 0x40010 +#define PRS_REG_FLUSH_REGIONS_TYPE_4 0x40014 +#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 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 */ +#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. */ +#define PRS_REG_NO_MATCH_EVENT_ID 0x40070 +/* [ST 24] The number of input CFC flush packets */ +#define PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES 0x40128 +/* [ST 32] The number of cycles the Parser halted its operation since it + could not allocate the next serial number */ +#define PRS_REG_NUM_OF_DEAD_CYCLES 0x40130 +/* [ST 24] The number of input packets */ +#define PRS_REG_NUM_OF_PACKETS 0x40124 +/* [ST 24] The number of input transparent flush packets */ +#define PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES 0x4012c +/* [RW 8] Context region for received Ethernet packet with a match and + packet type 0. Used in CFC load request message */ +#define PRS_REG_PACKET_REGIONS_TYPE_0 0x40028 +#define PRS_REG_PACKET_REGIONS_TYPE_1 0x4002c +#define PRS_REG_PACKET_REGIONS_TYPE_2 0x40030 +#define PRS_REG_PACKET_REGIONS_TYPE_3 0x40034 +#define PRS_REG_PACKET_REGIONS_TYPE_4 0x40038 +#define PRS_REG_PACKET_REGIONS_TYPE_5 0x4003c +#define PRS_REG_PACKET_REGIONS_TYPE_6 0x40040 +#define PRS_REG_PACKET_REGIONS_TYPE_7 0x40044 +/* [R 2] debug only: Number of pending requests for CAC on port 0. */ +#define PRS_REG_PENDING_BRB_CAC0_RQ 0x40174 +/* [R 2] debug only: Number of pending requests for header parsing. */ +#define PRS_REG_PENDING_BRB_PRS_RQ 0x40170 +/* [R 1] Interrupt register #0 read */ +#define PRS_REG_PRS_INT_STS 0x40188 +/* [RW 8] Parity mask register #0 read/write */ +#define PRS_REG_PRS_PRTY_MASK 0x401a4 +/* [RW 8] Context region for pure acknowledge packets. Used in CFC load + request message */ +#define PRS_REG_PURE_REGIONS 0x40024 +/* [R 32] debug only: Serial number status lsb 32 bits. '1' indicates this + serail number was released by SDM but cannot be used because a previous + serial number was not released. */ +#define PRS_REG_SERIAL_NUM_STATUS_LSB 0x40154 +/* [R 32] debug only: Serial number status msb 32 bits. '1' indicates this + serail number was released by SDM but cannot be used because a previous + serial number was not released. */ +#define PRS_REG_SERIAL_NUM_STATUS_MSB 0x40158 +/* [R 4] debug only: SRC current credit. Transaction based. */ +#define PRS_REG_SRC_CURRENT_CREDIT 0x4016c +/* [R 8] debug only: TCM current credit. Cycle based. */ +#define PRS_REG_TCM_CURRENT_CREDIT 0x40160 +/* [R 8] debug only: TSDM current credit. Transaction based. */ +#define PRS_REG_TSDM_CURRENT_CREDIT 0x4015c +/* [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 */ +#define PXP2_REG_HST_HEADER_FIFO_STATUS 0x120478 +#define PXP2_REG_PGL_CONTROL0 0x120490 +#define PXP2_REG_PGL_CONTROL1 0x120514 +/* [RW 32] Inbound interrupt table for CSDM: bits[31:16]-mask; + its[15:0]-address */ +#define PXP2_REG_PGL_INT_CSDM_0 0x1204f4 +#define PXP2_REG_PGL_INT_CSDM_1 0x1204f8 +#define PXP2_REG_PGL_INT_CSDM_2 0x1204fc +#define PXP2_REG_PGL_INT_CSDM_3 0x120500 +#define PXP2_REG_PGL_INT_CSDM_4 0x120504 +#define PXP2_REG_PGL_INT_CSDM_5 0x120508 +#define PXP2_REG_PGL_INT_CSDM_6 0x12050c +#define PXP2_REG_PGL_INT_CSDM_7 0x120510 +/* [RW 32] Inbound interrupt table for TSDM: bits[31:16]-mask; + its[15:0]-address */ +#define PXP2_REG_PGL_INT_TSDM_0 0x120494 +#define PXP2_REG_PGL_INT_TSDM_1 0x120498 +#define PXP2_REG_PGL_INT_TSDM_2 0x12049c +#define PXP2_REG_PGL_INT_TSDM_3 0x1204a0 +#define PXP2_REG_PGL_INT_TSDM_4 0x1204a4 +#define PXP2_REG_PGL_INT_TSDM_5 0x1204a8 +#define PXP2_REG_PGL_INT_TSDM_6 0x1204ac +#define PXP2_REG_PGL_INT_TSDM_7 0x1204b0 +/* [RW 32] Inbound interrupt table for USDM: bits[31:16]-mask; + its[15:0]-address */ +#define PXP2_REG_PGL_INT_USDM_0 0x1204b4 +#define PXP2_REG_PGL_INT_USDM_1 0x1204b8 +#define PXP2_REG_PGL_INT_USDM_2 0x1204bc +#define PXP2_REG_PGL_INT_USDM_3 0x1204c0 +#define PXP2_REG_PGL_INT_USDM_4 0x1204c4 +#define PXP2_REG_PGL_INT_USDM_5 0x1204c8 +#define PXP2_REG_PGL_INT_USDM_6 0x1204cc +#define PXP2_REG_PGL_INT_USDM_7 0x1204d0 +/* [RW 32] Inbound interrupt table for XSDM: bits[31:16]-mask; + its[15:0]-address */ +#define PXP2_REG_PGL_INT_XSDM_0 0x1204d4 +#define PXP2_REG_PGL_INT_XSDM_1 0x1204d8 +#define PXP2_REG_PGL_INT_XSDM_2 0x1204dc +#define PXP2_REG_PGL_INT_XSDM_3 0x1204e0 +#define PXP2_REG_PGL_INT_XSDM_4 0x1204e4 +#define PXP2_REG_PGL_INT_XSDM_5 0x1204e8 +#define PXP2_REG_PGL_INT_XSDM_6 0x1204ec +#define PXP2_REG_PGL_INT_XSDM_7 0x1204f0 +/* [R 1] this bit indicates that a read request was blocked because of + bus_master_en was deasserted */ +#define PXP2_REG_PGL_READ_BLOCKED 0x120568 +/* [R 6] debug only */ +#define PXP2_REG_PGL_TXR_CDTS 0x120528 +/* [R 18] debug only */ +#define PXP2_REG_PGL_TXW_CDTS 0x12052c +/* [R 1] this bit indicates that a write request was blocked because of + bus_master_en was deasserted */ +#define PXP2_REG_PGL_WRITE_BLOCKED 0x120564 +#define PXP2_REG_PSWRQ_BW_ADD1 0x1201c0 +#define PXP2_REG_PSWRQ_BW_ADD10 0x1201e4 +#define PXP2_REG_PSWRQ_BW_ADD11 0x1201e8 +#define PXP2_REG_PSWRQ_BW_ADD10 0x1201e4 +#define PXP2_REG_PSWRQ_BW_ADD11 0x1201e8 +#define PXP2_REG_PSWRQ_BW_ADD2 0x1201c4 +#define PXP2_REG_PSWRQ_BW_ADD28 0x120228 +#define PXP2_REG_PSWRQ_BW_ADD28 0x120228 +#define PXP2_REG_PSWRQ_BW_ADD3 0x1201c8 +#define PXP2_REG_PSWRQ_BW_ADD6 0x1201d4 +#define PXP2_REG_PSWRQ_BW_ADD7 0x1201d8 +#define PXP2_REG_PSWRQ_BW_ADD8 0x1201dc +#define PXP2_REG_PSWRQ_BW_ADD9 0x1201e0 +#define PXP2_REG_PSWRQ_BW_CREDIT 0x12032c +#define PXP2_REG_PSWRQ_BW_L1 0x1202b0 +#define PXP2_REG_PSWRQ_BW_L10 0x1202d4 +#define PXP2_REG_PSWRQ_BW_L11 0x1202d8 +#define PXP2_REG_PSWRQ_BW_L10 0x1202d4 +#define PXP2_REG_PSWRQ_BW_L11 0x1202d8 +#define PXP2_REG_PSWRQ_BW_L2 0x1202b4 +#define PXP2_REG_PSWRQ_BW_L28 0x120318 +#define PXP2_REG_PSWRQ_BW_L28 0x120318 +#define PXP2_REG_PSWRQ_BW_L3 0x1202b8 +#define PXP2_REG_PSWRQ_BW_L6 0x1202c4 +#define PXP2_REG_PSWRQ_BW_L7 0x1202c8 +#define PXP2_REG_PSWRQ_BW_L8 0x1202cc +#define PXP2_REG_PSWRQ_BW_L9 0x1202d0 +#define PXP2_REG_PSWRQ_BW_RD 0x120324 +#define PXP2_REG_PSWRQ_BW_UB1 0x120238 +#define PXP2_REG_PSWRQ_BW_UB10 0x12025c +#define PXP2_REG_PSWRQ_BW_UB11 0x120260 +#define PXP2_REG_PSWRQ_BW_UB10 0x12025c +#define PXP2_REG_PSWRQ_BW_UB11 0x120260 +#define PXP2_REG_PSWRQ_BW_UB2 0x12023c +#define PXP2_REG_PSWRQ_BW_UB28 0x1202a0 +#define PXP2_REG_PSWRQ_BW_UB28 0x1202a0 +#define PXP2_REG_PSWRQ_BW_UB3 0x120240 +#define PXP2_REG_PSWRQ_BW_UB6 0x12024c +#define PXP2_REG_PSWRQ_BW_UB7 0x120250 +#define PXP2_REG_PSWRQ_BW_UB8 0x120254 +#define PXP2_REG_PSWRQ_BW_UB9 0x120258 +#define PXP2_REG_PSWRQ_BW_WR 0x120328 +#define PXP2_REG_PSWRQ_CDU0_L2P 0x120000 +#define PXP2_REG_PSWRQ_QM0_L2P 0x120038 +#define PXP2_REG_PSWRQ_SRC0_L2P 0x120054 +#define PXP2_REG_PSWRQ_TM0_L2P 0x12001c +/* [RW 25] Interrupt mask register #0 read/write */ +#define PXP2_REG_PXP2_INT_MASK 0x120578 +/* [R 25] Interrupt register #0 read */ +#define PXP2_REG_PXP2_INT_STS 0x12056c +/* [RC 25] Interrupt register #0 read clear */ +#define PXP2_REG_PXP2_INT_STS_CLR 0x120570 +/* [RW 32] Parity mask register #0 read/write */ +#define PXP2_REG_PXP2_PRTY_MASK_0 0x120588 +#define PXP2_REG_PXP2_PRTY_MASK_1 0x120598 +/* [R 1] Debug only: The 'almost full' indication from each fifo (gives + indication about backpressure) */ +#define PXP2_REG_RD_ALMOST_FULL_0 0x120424 +/* [R 8] Debug only: The blocks counter - number of unused block ids */ +#define PXP2_REG_RD_BLK_CNT 0x120418 +/* [RW 8] Debug only: Total number of available blocks in Tetris Buffer. + Must be bigger than 6. Normally should not be changed. */ +#define PXP2_REG_RD_BLK_NUM_CFG 0x12040c +/* [RW 2] CDU byte swapping mode configuration for master read requests */ +#define PXP2_REG_RD_CDURD_SWAP_MODE 0x120404 +/* [RW 1] When '1'; inputs to the PSWRD block are ignored */ +#define PXP2_REG_RD_DISABLE_INPUTS 0x120374 +/* [R 1] PSWRD internal memories initialization is done */ +#define PXP2_REG_RD_INIT_DONE 0x120370 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq10 */ +#define PXP2_REG_RD_MAX_BLKS_VQ10 0x1203a0 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq11 */ +#define PXP2_REG_RD_MAX_BLKS_VQ11 0x1203a4 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq17 */ +#define PXP2_REG_RD_MAX_BLKS_VQ17 0x1203bc +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq18 */ +#define PXP2_REG_RD_MAX_BLKS_VQ18 0x1203c0 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq19 */ +#define PXP2_REG_RD_MAX_BLKS_VQ19 0x1203c4 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq22 */ +#define PXP2_REG_RD_MAX_BLKS_VQ22 0x1203d0 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq6 */ +#define PXP2_REG_RD_MAX_BLKS_VQ6 0x120390 +/* [RW 8] The maximum number of blocks in Tetris Buffer that can be + allocated for vq9 */ +#define PXP2_REG_RD_MAX_BLKS_VQ9 0x12039c +/* [RW 2] PBF byte swapping mode configuration for master read requests */ +#define PXP2_REG_RD_PBF_SWAP_MODE 0x1203f4 +/* [R 1] Debug only: Indication if delivery ports are idle */ +#define PXP2_REG_RD_PORT_IS_IDLE_0 0x12041c +#define PXP2_REG_RD_PORT_IS_IDLE_1 0x120420 +/* [RW 2] QM byte swapping mode configuration for master read requests */ +#define PXP2_REG_RD_QM_SWAP_MODE 0x1203f8 +/* [R 7] Debug only: The SR counter - number of unused sub request ids */ +#define PXP2_REG_RD_SR_CNT 0x120414 +/* [RW 2] SRC byte swapping mode configuration for master read requests */ +#define PXP2_REG_RD_SRC_SWAP_MODE 0x120400 +/* [RW 7] Debug only: Total number of available PCI read sub-requests. Must + be bigger than 1. Normally should not be changed. */ +#define PXP2_REG_RD_SR_NUM_CFG 0x120408 +/* [RW 1] Signals the PSWRD block to start initializing internal memories */ +#define PXP2_REG_RD_START_INIT 0x12036c +/* [RW 2] TM byte swapping mode configuration for master read requests */ +#define PXP2_REG_RD_TM_SWAP_MODE 0x1203fc +/* [RW 10] Bandwidth addition to VQ0 write requests */ +#define PXP2_REG_RQ_BW_RD_ADD0 0x1201bc +/* [RW 10] Bandwidth addition to VQ12 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD12 0x1201ec +/* [RW 10] Bandwidth addition to VQ13 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD13 0x1201f0 +/* [RW 10] Bandwidth addition to VQ14 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD14 0x1201f4 +/* [RW 10] Bandwidth addition to VQ15 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD15 0x1201f8 +/* [RW 10] Bandwidth addition to VQ16 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD16 0x1201fc +/* [RW 10] Bandwidth addition to VQ17 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD17 0x120200 +/* [RW 10] Bandwidth addition to VQ18 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD18 0x120204 +/* [RW 10] Bandwidth addition to VQ19 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD19 0x120208 +/* [RW 10] Bandwidth addition to VQ20 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD20 0x12020c +/* [RW 10] Bandwidth addition to VQ22 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD22 0x120210 +/* [RW 10] Bandwidth addition to VQ23 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD23 0x120214 +/* [RW 10] Bandwidth addition to VQ24 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD24 0x120218 +/* [RW 10] Bandwidth addition to VQ25 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD25 0x12021c +/* [RW 10] Bandwidth addition to VQ26 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD26 0x120220 +/* [RW 10] Bandwidth addition to VQ27 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD27 0x120224 +/* [RW 10] Bandwidth addition to VQ4 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD4 0x1201cc +/* [RW 10] Bandwidth addition to VQ5 read requests */ +#define PXP2_REG_RQ_BW_RD_ADD5 0x1201d0 +/* [RW 10] Bandwidth Typical L for VQ0 Read requests */ +#define PXP2_REG_RQ_BW_RD_L0 0x1202ac +/* [RW 10] Bandwidth Typical L for VQ12 Read requests */ +#define PXP2_REG_RQ_BW_RD_L12 0x1202dc +/* [RW 10] Bandwidth Typical L for VQ13 Read requests */ +#define PXP2_REG_RQ_BW_RD_L13 0x1202e0 +/* [RW 10] Bandwidth Typical L for VQ14 Read requests */ +#define PXP2_REG_RQ_BW_RD_L14 0x1202e4 +/* [RW 10] Bandwidth Typical L for VQ15 Read requests */ +#define PXP2_REG_RQ_BW_RD_L15 0x1202e8 +/* [RW 10] Bandwidth Typical L for VQ16 Read requests */ +#define PXP2_REG_RQ_BW_RD_L16 0x1202ec +/* [RW 10] Bandwidth Typical L for VQ17 Read requests */ +#define PXP2_REG_RQ_BW_RD_L17 0x1202f0 +/* [RW 10] Bandwidth Typical L for VQ18 Read requests */ +#define PXP2_REG_RQ_BW_RD_L18 0x1202f4 +/* [RW 10] Bandwidth Typical L for VQ19 Read requests */ +#define PXP2_REG_RQ_BW_RD_L19 0x1202f8 +/* [RW 10] Bandwidth Typical L for VQ20 Read requests */ +#define PXP2_REG_RQ_BW_RD_L20 0x1202fc +/* [RW 10] Bandwidth Typical L for VQ22 Read requests */ +#define PXP2_REG_RQ_BW_RD_L22 0x120300 +/* [RW 10] Bandwidth Typical L for VQ23 Read requests */ +#define PXP2_REG_RQ_BW_RD_L23 0x120304 +/* [RW 10] Bandwidth Typical L for VQ24 Read requests */ +#define PXP2_REG_RQ_BW_RD_L24 0x120308 +/* [RW 10] Bandwidth Typical L for VQ25 Read requests */ +#define PXP2_REG_RQ_BW_RD_L25 0x12030c +/* [RW 10] Bandwidth Typical L for VQ26 Read requests */ +#define PXP2_REG_RQ_BW_RD_L26 0x120310 +/* [RW 10] Bandwidth Typical L for VQ27 Read requests */ +#define PXP2_REG_RQ_BW_RD_L27 0x120314 +/* [RW 10] Bandwidth Typical L for VQ4 Read requests */ +#define PXP2_REG_RQ_BW_RD_L4 0x1202bc +/* [RW 10] Bandwidth Typical L for VQ5 Read- currently not used */ +#define PXP2_REG_RQ_BW_RD_L5 0x1202c0 +/* [RW 7] Bandwidth upper bound for VQ0 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND0 0x120234 +/* [RW 7] Bandwidth upper bound for VQ12 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND12 0x120264 +/* [RW 7] Bandwidth upper bound for VQ13 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND13 0x120268 +/* [RW 7] Bandwidth upper bound for VQ14 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND14 0x12026c +/* [RW 7] Bandwidth upper bound for VQ15 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND15 0x120270 +/* [RW 7] Bandwidth upper bound for VQ16 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND16 0x120274 +/* [RW 7] Bandwidth upper bound for VQ17 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND17 0x120278 +/* [RW 7] Bandwidth upper bound for VQ18 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND18 0x12027c +/* [RW 7] Bandwidth upper bound for VQ19 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND19 0x120280 +/* [RW 7] Bandwidth upper bound for VQ20 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND20 0x120284 +/* [RW 7] Bandwidth upper bound for VQ22 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND22 0x120288 +/* [RW 7] Bandwidth upper bound for VQ23 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND23 0x12028c +/* [RW 7] Bandwidth upper bound for VQ24 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND24 0x120290 +/* [RW 7] Bandwidth upper bound for VQ25 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND25 0x120294 +/* [RW 7] Bandwidth upper bound for VQ26 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND26 0x120298 +/* [RW 7] Bandwidth upper bound for VQ27 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND27 0x12029c +/* [RW 7] Bandwidth upper bound for VQ4 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND4 0x120244 +/* [RW 7] Bandwidth upper bound for VQ5 read requests */ +#define PXP2_REG_RQ_BW_RD_UBOUND5 0x120248 +/* [RW 10] Bandwidth addition to VQ29 write requests */ +#define PXP2_REG_RQ_BW_WR_ADD29 0x12022c +/* [RW 10] Bandwidth addition to VQ30 write requests */ +#define PXP2_REG_RQ_BW_WR_ADD30 0x120230 +/* [RW 10] Bandwidth Typical L for VQ29 Write requests */ +#define PXP2_REG_RQ_BW_WR_L29 0x12031c +/* [RW 10] Bandwidth Typical L for VQ30 Write requests */ +#define PXP2_REG_RQ_BW_WR_L30 0x120320 +/* [RW 7] Bandwidth upper bound for VQ29 */ +#define PXP2_REG_RQ_BW_WR_UBOUND29 0x1202a4 +/* [RW 7] Bandwidth upper bound for VQ30 */ +#define PXP2_REG_RQ_BW_WR_UBOUND30 0x1202a8 +/* [RW 2] Endian mode for cdu */ +#define PXP2_REG_RQ_CDU_ENDIAN_M 0x1201a0 +/* [RW 3] page size in L2P table for CDU module; -4k; -8k; -16k; -32k; -64k; + -128k */ +#define PXP2_REG_RQ_CDU_P_SIZE 0x120018 +/* [R 1] 1' indicates that the requester has finished its internal + configuration */ +#define PXP2_REG_RQ_CFG_DONE 0x1201b4 +/* [RW 2] Endian mode for debug */ +#define PXP2_REG_RQ_DBG_ENDIAN_M 0x1201a4 +/* [RW 1] When '1'; requests will enter input buffers but wont get out + towards the glue */ +#define PXP2_REG_RQ_DISABLE_INPUTS 0x120330 +/* [RW 2] Endian mode for hc */ +#define PXP2_REG_RQ_HC_ENDIAN_M 0x1201a8 +/* [WB 53] Onchip address table */ +#define PXP2_REG_RQ_ONCHIP_AT 0x122000 +/* [RW 2] Endian mode for qm */ +#define PXP2_REG_RQ_QM_ENDIAN_M 0x120194 +/* [RW 3] page size in L2P table for QM module; -4k; -8k; -16k; -32k; -64k; + -128k */ +#define PXP2_REG_RQ_QM_P_SIZE 0x120050 +/* [RW 1] 1' indicates that the RBC has finished configurating the PSWRQ */ +#define PXP2_REG_RQ_RBC_DONE 0x1201b0 +/* [RW 3] Max burst size filed for read requests port 0; 000 - 128B; + 001:256B; 010: 512B; 11:1K:100:2K; 01:4K */ +#define PXP2_REG_RQ_RD_MBS0 0x120160 +/* [RW 2] Endian mode for src */ +#define PXP2_REG_RQ_SRC_ENDIAN_M 0x12019c +/* [RW 3] page size in L2P table for SRC module; -4k; -8k; -16k; -32k; -64k; + -128k */ +#define PXP2_REG_RQ_SRC_P_SIZE 0x12006c +/* [RW 2] Endian mode for tm */ +#define PXP2_REG_RQ_TM_ENDIAN_M 0x120198 +/* [RW 3] page size in L2P table for TM module; -4k; -8k; -16k; -32k; -64k; + -128k */ +#define PXP2_REG_RQ_TM_P_SIZE 0x120034 +/* [R 5] Number of entries in the ufifo; his fifo has l2p completions */ +#define PXP2_REG_RQ_UFIFO_NUM_OF_ENTRY 0x12080c +/* [R 8] Number of entries occupied by vq 0 in pswrq memory */ +#define PXP2_REG_RQ_VQ0_ENTRY_CNT 0x120810 +/* [R 8] Number of entries occupied by vq 10 in pswrq memory */ +#define PXP2_REG_RQ_VQ10_ENTRY_CNT 0x120818 +/* [R 8] Number of entries occupied by vq 11 in pswrq memory */ +#define PXP2_REG_RQ_VQ11_ENTRY_CNT 0x120820 +/* [R 8] Number of entries occupied by vq 12 in pswrq memory */ +#define PXP2_REG_RQ_VQ12_ENTRY_CNT 0x120828 +/* [R 8] Number of entries occupied by vq 13 in pswrq memory */ +#define PXP2_REG_RQ_VQ13_ENTRY_CNT 0x120830 +/* [R 8] Number of entries occupied by vq 14 in pswrq memory */ +#define PXP2_REG_RQ_VQ14_ENTRY_CNT 0x120838 +/* [R 8] Number of entries occupied by vq 15 in pswrq memory */ +#define PXP2_REG_RQ_VQ15_ENTRY_CNT 0x120840 +/* [R 8] Number of entries occupied by vq 16 in pswrq memory */ +#define PXP2_REG_RQ_VQ16_ENTRY_CNT 0x120848 +/* [R 8] Number of entries occupied by vq 17 in pswrq memory */ +#define PXP2_REG_RQ_VQ17_ENTRY_CNT 0x120850 +/* [R 8] Number of entries occupied by vq 18 in pswrq memory */ +#define PXP2_REG_RQ_VQ18_ENTRY_CNT 0x120858 +/* [R 8] Number of entries occupied by vq 19 in pswrq memory */ +#define PXP2_REG_RQ_VQ19_ENTRY_CNT 0x120860 +/* [R 8] Number of entries occupied by vq 1 in pswrq memory */ +#define PXP2_REG_RQ_VQ1_ENTRY_CNT 0x120868 +/* [R 8] Number of entries occupied by vq 20 in pswrq memory */ +#define PXP2_REG_RQ_VQ20_ENTRY_CNT 0x120870 +/* [R 8] Number of entries occupied by vq 21 in pswrq memory */ +#define PXP2_REG_RQ_VQ21_ENTRY_CNT 0x120878 +/* [R 8] Number of entries occupied by vq 22 in pswrq memory */ +#define PXP2_REG_RQ_VQ22_ENTRY_CNT 0x120880 +/* [R 8] Number of entries occupied by vq 23 in pswrq memory */ +#define PXP2_REG_RQ_VQ23_ENTRY_CNT 0x120888 +/* [R 8] Number of entries occupied by vq 24 in pswrq memory */ +#define PXP2_REG_RQ_VQ24_ENTRY_CNT 0x120890 +/* [R 8] Number of entries occupied by vq 25 in pswrq memory */ +#define PXP2_REG_RQ_VQ25_ENTRY_CNT 0x120898 +/* [R 8] Number of entries occupied by vq 26 in pswrq memory */ +#define PXP2_REG_RQ_VQ26_ENTRY_CNT 0x1208a0 +/* [R 8] Number of entries occupied by vq 27 in pswrq memory */ +#define PXP2_REG_RQ_VQ27_ENTRY_CNT 0x1208a8 +/* [R 8] Number of entries occupied by vq 28 in pswrq memory */ +#define PXP2_REG_RQ_VQ28_ENTRY_CNT 0x1208b0 +/* [R 8] Number of entries occupied by vq 29 in pswrq memory */ +#define PXP2_REG_RQ_VQ29_ENTRY_CNT 0x1208b8 +/* [R 8] Number of entries occupied by vq 2 in pswrq memory */ +#define PXP2_REG_RQ_VQ2_ENTRY_CNT 0x1208c0 +/* [R 8] Number of entries occupied by vq 30 in pswrq memory */ +#define PXP2_REG_RQ_VQ30_ENTRY_CNT 0x1208c8 +/* [R 8] Number of entries occupied by vq 31 in pswrq memory */ +#define PXP2_REG_RQ_VQ31_ENTRY_CNT 0x1208d0 +/* [R 8] Number of entries occupied by vq 3 in pswrq memory */ +#define PXP2_REG_RQ_VQ3_ENTRY_CNT 0x1208d8 +/* [R 8] Number of entries occupied by vq 4 in pswrq memory */ +#define PXP2_REG_RQ_VQ4_ENTRY_CNT 0x1208e0 +/* [R 8] Number of entries occupied by vq 5 in pswrq memory */ +#define PXP2_REG_RQ_VQ5_ENTRY_CNT 0x1208e8 +/* [R 8] Number of entries occupied by vq 6 in pswrq memory */ +#define PXP2_REG_RQ_VQ6_ENTRY_CNT 0x1208f0 +/* [R 8] Number of entries occupied by vq 7 in pswrq memory */ +#define PXP2_REG_RQ_VQ7_ENTRY_CNT 0x1208f8 +/* [R 8] Number of entries occupied by vq 8 in pswrq memory */ +#define PXP2_REG_RQ_VQ8_ENTRY_CNT 0x120900 +/* [R 8] Number of entries occupied by vq 9 in pswrq memory */ +#define PXP2_REG_RQ_VQ9_ENTRY_CNT 0x120908 +/* [RW 3] Max burst size filed for write requests port 0; 000 - 128B; + 001:256B; 010: 512B; */ +#define PXP2_REG_RQ_WR_MBS0 0x12015c +/* [RW 10] if Number of entries in dmae fifo will be higer than this + threshold then has_payload indication will be asserted; the default value + should be equal to > write MBS size! */ +#define PXP2_REG_WR_DMAE_TH 0x120368 +/* [R 1] debug only: Indication if PSWHST arbiter is idle */ +#define PXP_REG_HST_ARB_IS_IDLE 0x103004 +/* [R 8] debug only: A bit mask for all PSWHST arbiter clients. '1' means + this client is waiting for the arbiter. */ +#define PXP_REG_HST_CLIENTS_WAITING_TO_ARB 0x103008 +/* [WB 160] Used for initialization of the inbound interrupts memory */ +#define PXP_REG_HST_INBOUND_INT 0x103800 +/* [RW 32] Interrupt mask register #0 read/write */ +#define PXP_REG_PXP_INT_MASK_0 0x103074 +#define PXP_REG_PXP_INT_MASK_1 0x103084 +/* [R 32] Interrupt register #0 read */ +#define PXP_REG_PXP_INT_STS_0 0x103068 +#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_PRTY_MASK 0x103094 +/* [RW 4] The activity counter initial increment value sent in the load + request */ +#define QM_REG_ACTCTRINITVAL_0 0x168040 +#define QM_REG_ACTCTRINITVAL_1 0x168044 +#define QM_REG_ACTCTRINITVAL_2 0x168048 +#define QM_REG_ACTCTRINITVAL_3 0x16804c +/* [RW 32] The base logical address (in bytes) of each physical queue. The + index I represents the physical queue number. The 12 lsbs are ignore and + considered zero so practically there are only 20 bits in this register. */ +#define QM_REG_BASEADDR 0x168900 +/* [RW 16] The byte credit cost for each task. This value is for both ports */ +#define QM_REG_BYTECRDCOST 0x168234 +/* [RW 16] The initial byte credit value for both ports. */ +#define QM_REG_BYTECRDINITVAL 0x168238 +/* [RW 32] A bit per physical queue. If the bit is cleared then the physical + queue uses port 0 else it uses port 1. */ +#define QM_REG_BYTECRDPORT_LSB 0x168228 +/* [RW 32] A bit per physical queue. If the bit is cleared then the physical + queue uses port 0 else it uses port 1. */ +#define QM_REG_BYTECRDPORT_MSB 0x168224 +/* [RW 16] The byte credit value that if above the QM is considered almost + full */ +#define QM_REG_BYTECREDITAFULLTHR 0x168094 +/* [RW 4] The initial credit for interface */ +#define QM_REG_CMINITCRD_0 0x1680cc +#define QM_REG_CMINITCRD_1 0x1680d0 +#define QM_REG_CMINITCRD_2 0x1680d4 +#define QM_REG_CMINITCRD_3 0x1680d8 +#define QM_REG_CMINITCRD_4 0x1680dc +#define QM_REG_CMINITCRD_5 0x1680e0 +#define QM_REG_CMINITCRD_6 0x1680e4 +#define QM_REG_CMINITCRD_7 0x1680e8 +/* [RW 8] A mask bit per CM interface. If this bit is 0 then this interface + is masked */ +#define QM_REG_CMINTEN 0x1680ec +/* [RW 12] A bit vector which indicates which one of the queues are tied to + interface 0 */ +#define QM_REG_CMINTVOQMASK_0 0x1681f4 +#define QM_REG_CMINTVOQMASK_1 0x1681f8 +#define QM_REG_CMINTVOQMASK_2 0x1681fc +#define QM_REG_CMINTVOQMASK_3 0x168200 +#define QM_REG_CMINTVOQMASK_4 0x168204 +#define QM_REG_CMINTVOQMASK_5 0x168208 +#define QM_REG_CMINTVOQMASK_6 0x16820c +#define QM_REG_CMINTVOQMASK_7 0x168210 +/* [RW 20] The number of connections divided by 16 which dictates the size + of each queue per port 0 */ +#define QM_REG_CONNNUM_0 0x168020 +/* [R 6] Keep the fill level of the fifo from write client 4 */ +#define QM_REG_CQM_WRC_FIFOLVL 0x168018 +/* [RW 8] The context regions sent in the CFC load request */ +#define QM_REG_CTXREG_0 0x168030 +#define QM_REG_CTXREG_1 0x168034 +#define QM_REG_CTXREG_2 0x168038 +#define QM_REG_CTXREG_3 0x16803c +/* [RW 12] The VOQ mask used to select the VOQs which needs to be full for + bypass enable */ +#define QM_REG_ENBYPVOQMASK 0x16823c +/* [RW 32] A bit mask per each physical queue. If a bit is set then the + physical queue uses the byte credit */ +#define QM_REG_ENBYTECRD_LSB 0x168220 +/* [RW 32] A bit mask per each physical queue. If a bit is set then the + physical queue uses the byte credit */ +#define QM_REG_ENBYTECRD_MSB 0x16821c +/* [RW 4] If cleared then the secondary interface will not be served by the + RR arbiter */ +#define QM_REG_ENSEC 0x1680f0 +/* [RW 32] A bit vector per each physical queue which selects which function + number to use on PCI access for that queue. */ +#define QM_REG_FUNCNUMSEL_LSB 0x168230 +/* [RW 32] A bit vector per each physical queue which selects which function + number to use on PCI access for that queue. */ +#define QM_REG_FUNCNUMSEL_MSB 0x16822c +/* [RW 32] A mask register to mask the Almost empty signals which will not + be use for the almost empty indication to the HW block */ +#define QM_REG_HWAEMPTYMASK_LSB 0x168218 +/* [RW 32] A mask register to mask the Almost empty signals which will not + be use for the almost empty indication to the HW block */ +#define QM_REG_HWAEMPTYMASK_MSB 0x168214 +/* [RW 4] The number of outstanding request to CFC */ +#define QM_REG_OUTLDREQ 0x168804 +/* [RC 1] A flag to indicate that overflow error occurred in one of the + queues. */ +#define QM_REG_OVFERROR 0x16805c +/* [RC 6] the Q were the qverflow occurs */ +#define QM_REG_OVFQNUM 0x168058 +/* [R 32] Pause state for physical queues 31-0 */ +#define QM_REG_PAUSESTATE0 0x168410 +/* [R 32] Pause state for physical queues 64-32 */ +#define QM_REG_PAUSESTATE1 0x168414 +/* [RW 2] The PCI attributes field used in the PCI request. */ +#define QM_REG_PCIREQAT 0x168054 +/* [R 16] The byte credit of port 0 */ +#define QM_REG_PORT0BYTECRD 0x168300 +/* [R 16] The byte credit of port 1 */ +#define QM_REG_PORT1BYTECRD 0x168304 +/* [WB 54] Pointer Table Memory; The mapping is as follow: ptrtbl[53:30] + read pointer; ptrtbl[29:6] write pointer; ptrtbl[5:4] read bank0; + ptrtbl[3:2] read bank 1; ptrtbl[1:0] write bank; */ +#define QM_REG_PTRTBL 0x168a00 +/* [RW 2] Interrupt mask register #0 read/write */ +#define QM_REG_QM_INT_MASK 0x168444 +/* [R 2] Interrupt register #0 read */ +#define QM_REG_QM_INT_STS 0x168438 +/* [RW 9] Parity mask register #0 read/write */ +#define QM_REG_QM_PRTY_MASK 0x168454 +/* [R 32] Current queues in pipeline: Queues from 32 to 63 */ +#define QM_REG_QSTATUS_HIGH 0x16802c +/* [R 32] Current queues in pipeline: Queues from 0 to 31 */ +#define QM_REG_QSTATUS_LOW 0x168028 +/* [R 24] The number of tasks queued for each queue */ +#define QM_REG_QTASKCTR_0 0x168308 +/* [RW 4] Queue tied to VOQ */ +#define QM_REG_QVOQIDX_0 0x1680f4 +#define QM_REG_QVOQIDX_10 0x16811c +#define QM_REG_QVOQIDX_11 0x168120 +#define QM_REG_QVOQIDX_12 0x168124 +#define QM_REG_QVOQIDX_13 0x168128 +#define QM_REG_QVOQIDX_14 0x16812c +#define QM_REG_QVOQIDX_15 0x168130 +#define QM_REG_QVOQIDX_16 0x168134 +#define QM_REG_QVOQIDX_17 0x168138 +#define QM_REG_QVOQIDX_21 0x168148 +#define QM_REG_QVOQIDX_25 0x168158 +#define QM_REG_QVOQIDX_29 0x168168 +#define QM_REG_QVOQIDX_32 0x168174 +#define QM_REG_QVOQIDX_33 0x168178 +#define QM_REG_QVOQIDX_34 0x16817c +#define QM_REG_QVOQIDX_35 0x168180 +#define QM_REG_QVOQIDX_36 0x168184 +#define QM_REG_QVOQIDX_37 0x168188 +#define QM_REG_QVOQIDX_38 0x16818c +#define QM_REG_QVOQIDX_39 0x168190 +#define QM_REG_QVOQIDX_40 0x168194 +#define QM_REG_QVOQIDX_41 0x168198 +#define QM_REG_QVOQIDX_42 0x16819c +#define QM_REG_QVOQIDX_43 0x1681a0 +#define QM_REG_QVOQIDX_44 0x1681a4 +#define QM_REG_QVOQIDX_45 0x1681a8 +#define QM_REG_QVOQIDX_46 0x1681ac +#define QM_REG_QVOQIDX_47 0x1681b0 +#define QM_REG_QVOQIDX_48 0x1681b4 +#define QM_REG_QVOQIDX_49 0x1681b8 +#define QM_REG_QVOQIDX_5 0x168108 +#define QM_REG_QVOQIDX_50 0x1681bc +#define QM_REG_QVOQIDX_51 0x1681c0 +#define QM_REG_QVOQIDX_52 0x1681c4 +#define QM_REG_QVOQIDX_53 0x1681c8 +#define QM_REG_QVOQIDX_54 0x1681cc +#define QM_REG_QVOQIDX_55 0x1681d0 +#define QM_REG_QVOQIDX_56 0x1681d4 +#define QM_REG_QVOQIDX_57 0x1681d8 +#define QM_REG_QVOQIDX_58 0x1681dc +#define QM_REG_QVOQIDX_59 0x1681e0 +#define QM_REG_QVOQIDX_50 0x1681bc +#define QM_REG_QVOQIDX_51 0x1681c0 +#define QM_REG_QVOQIDX_52 0x1681c4 +#define QM_REG_QVOQIDX_53 0x1681c8 +#define QM_REG_QVOQIDX_54 0x1681cc +#define QM_REG_QVOQIDX_55 0x1681d0 +#define QM_REG_QVOQIDX_56 0x1681d4 +#define QM_REG_QVOQIDX_57 0x1681d8 +#define QM_REG_QVOQIDX_58 0x1681dc +#define QM_REG_QVOQIDX_59 0x1681e0 +#define QM_REG_QVOQIDX_6 0x16810c +#define QM_REG_QVOQIDX_60 0x1681e4 +#define QM_REG_QVOQIDX_61 0x1681e8 +#define QM_REG_QVOQIDX_62 0x1681ec +#define QM_REG_QVOQIDX_63 0x1681f0 +#define QM_REG_QVOQIDX_60 0x1681e4 +#define QM_REG_QVOQIDX_61 0x1681e8 +#define QM_REG_QVOQIDX_62 0x1681ec +#define QM_REG_QVOQIDX_63 0x1681f0 +#define QM_REG_QVOQIDX_7 0x168110 +#define QM_REG_QVOQIDX_8 0x168114 +#define QM_REG_QVOQIDX_9 0x168118 +/* [R 24] Remaining pause timeout for port 0 */ +#define QM_REG_REMAINPAUSETM0 0x168418 +/* [R 24] Remaining pause timeout for port 1 */ +#define QM_REG_REMAINPAUSETM1 0x16841c +/* [RW 1] Initialization bit command */ +#define QM_REG_SOFT_RESET 0x168428 +/* [RW 8] The credit cost per every task in the QM. A value per each VOQ */ +#define QM_REG_TASKCRDCOST_0 0x16809c +#define QM_REG_TASKCRDCOST_1 0x1680a0 +#define QM_REG_TASKCRDCOST_10 0x1680c4 +#define QM_REG_TASKCRDCOST_11 0x1680c8 +#define QM_REG_TASKCRDCOST_2 0x1680a4 +#define QM_REG_TASKCRDCOST_4 0x1680ac +#define QM_REG_TASKCRDCOST_5 0x1680b0 +/* [R 6] Keep the fill level of the fifo from write client 3 */ +#define QM_REG_TQM_WRC_FIFOLVL 0x168010 +/* [R 6] Keep the fill level of the fifo from write client 2 */ +#define QM_REG_UQM_WRC_FIFOLVL 0x168008 +/* [RC 32] Credit update error register */ +#define QM_REG_VOQCRDERRREG 0x168408 +/* [R 16] The credit value for each VOQ */ +#define QM_REG_VOQCREDIT_0 0x1682d0 +#define QM_REG_VOQCREDIT_1 0x1682d4 +#define QM_REG_VOQCREDIT_10 0x1682f8 +#define QM_REG_VOQCREDIT_11 0x1682fc +#define QM_REG_VOQCREDIT_4 0x1682e0 +/* [RW 16] The credit value that if above the QM is considered almost full */ +#define QM_REG_VOQCREDITAFULLTHR 0x168090 +/* [RW 16] The init and maximum credit for each VoQ */ +#define QM_REG_VOQINITCREDIT_0 0x168060 +#define QM_REG_VOQINITCREDIT_1 0x168064 +#define QM_REG_VOQINITCREDIT_10 0x168088 +#define QM_REG_VOQINITCREDIT_11 0x16808c +#define QM_REG_VOQINITCREDIT_2 0x168068 +#define QM_REG_VOQINITCREDIT_4 0x168070 +#define QM_REG_VOQINITCREDIT_5 0x168074 +/* [RW 1] The port of which VOQ belongs */ +#define QM_REG_VOQPORT_1 0x1682a4 +#define QM_REG_VOQPORT_10 0x1682c8 +#define QM_REG_VOQPORT_11 0x1682cc +#define QM_REG_VOQPORT_2 0x1682a8 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_0_LSB 0x168240 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_0_MSB 0x168244 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_1_MSB 0x16824c +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_2_LSB 0x168250 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_2_MSB 0x168254 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_3_LSB 0x168258 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_4_LSB 0x168260 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_4_MSB 0x168264 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_5_LSB 0x168268 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_5_MSB 0x16826c +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_6_LSB 0x168270 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_6_MSB 0x168274 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_7_LSB 0x168278 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_7_MSB 0x16827c +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_8_LSB 0x168280 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_8_MSB 0x168284 +/* [RW 32] The physical queue number associated with each VOQ */ +#define QM_REG_VOQQMASK_9_LSB 0x168288 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_0 0x16880c +#define QM_REG_WRRWEIGHTS_1 0x168810 +#define QM_REG_WRRWEIGHTS_10 0x168814 +#define QM_REG_WRRWEIGHTS_10_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_11 0x168818 +#define QM_REG_WRRWEIGHTS_11_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_12 0x16881c +#define QM_REG_WRRWEIGHTS_12_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_13 0x168820 +#define QM_REG_WRRWEIGHTS_13_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_14 0x168824 +#define QM_REG_WRRWEIGHTS_14_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_15 0x168828 +#define QM_REG_WRRWEIGHTS_15_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_10 0x168814 +#define QM_REG_WRRWEIGHTS_11 0x168818 +#define QM_REG_WRRWEIGHTS_12 0x16881c +#define QM_REG_WRRWEIGHTS_13 0x168820 +#define QM_REG_WRRWEIGHTS_14 0x168824 +#define QM_REG_WRRWEIGHTS_15 0x168828 +#define QM_REG_WRRWEIGHTS_2 0x16882c +#define QM_REG_WRRWEIGHTS_3 0x168830 +#define QM_REG_WRRWEIGHTS_4 0x168834 +#define QM_REG_WRRWEIGHTS_5 0x168838 +#define QM_REG_WRRWEIGHTS_6 0x16883c +#define QM_REG_WRRWEIGHTS_7 0x168840 +#define QM_REG_WRRWEIGHTS_8 0x168844 +#define QM_REG_WRRWEIGHTS_9 0x168848 +/* [R 6] Keep the fill level of the fifo from write client 1 */ +#define QM_REG_XQM_WRC_FIFOLVL 0x168000 +#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define DORQ_DORQ_INT_STS_REG_ADDRESS_ERROR_SIZE 0 +#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0) +#define DORQ_DORQ_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0 +#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0) +#define DORQ_DORQ_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0 +#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR (0x1<<0) +#define DORQ_DORQ_INT_MASK_REG_ADDRESS_ERROR_SIZE 0 +#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR (0x1<<0) +#define NIG_NIG_INT_STS_0_REG_ADDRESS_ERROR_SIZE 0 +#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR (0x1<<0) +#define NIG_NIG_INT_STS_CLR_0_REG_ADDRESS_ERROR_SIZE 0 +#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR (0x1<<0) +#define NIG_NIG_INT_STS_WR_0_REG_ADDRESS_ERROR_SIZE 0 +#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR (0x1<<0) +#define NIG_NIG_INT_MASK_0_REG_ADDRESS_ERROR_SIZE 0 +#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define TCM_TCM_INT_STS_REG_ADDRESS_ERROR_SIZE 0 +#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR (0x1<<0) +#define TCM_TCM_INT_STS_CLR_REG_ADDRESS_ERROR_SIZE 0 +#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR (0x1<<0) +#define TCM_TCM_INT_STS_WR_REG_ADDRESS_ERROR_SIZE 0 +#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR (0x1<<0) +#define TCM_TCM_INT_MASK_REG_ADDRESS_ERROR_SIZE 0 +#define CFC_DEBUG1_REG_WRITE_AC (0x1<<4) +#define CFC_DEBUG1_REG_WRITE_AC_SIZE 4 +/* [R 1] debug only: This bit indicates wheter indicates that external + buffer was wrapped (oldest data was thrown); Relevant only when + ~dbg_registers_debug_target=2 (PCI) & ~dbg_registers_full_mode=1 (wrap); */ +#define DBG_REG_WRAP_ON_EXT_BUFFER 0xc124 +#define DBG_REG_WRAP_ON_EXT_BUFFER_SIZE 1 +/* [R 1] debug only: This bit indicates wheter the internal buffer was + wrapped (oldest data was thrown) Relevant only when + ~dbg_registers_debug_target=0 (internal buffer) */ +#define DBG_REG_WRAP_ON_INT_BUFFER 0xc128 +#define DBG_REG_WRAP_ON_INT_BUFFER_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_0 0x16880c +#define QM_REG_WRRWEIGHTS_0_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_1 0x168810 +#define QM_REG_WRRWEIGHTS_1_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_10 0x168814 +#define QM_REG_WRRWEIGHTS_10_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_11 0x168818 +#define QM_REG_WRRWEIGHTS_11_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_12 0x16881c +#define QM_REG_WRRWEIGHTS_12_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_13 0x168820 +#define QM_REG_WRRWEIGHTS_13_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_14 0x168824 +#define QM_REG_WRRWEIGHTS_14_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_15 0x168828 +#define QM_REG_WRRWEIGHTS_15_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_2 0x16882c +#define QM_REG_WRRWEIGHTS_2_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_3 0x168830 +#define QM_REG_WRRWEIGHTS_3_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_4 0x168834 +#define QM_REG_WRRWEIGHTS_4_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_5 0x168838 +#define QM_REG_WRRWEIGHTS_5_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_6 0x16883c +#define QM_REG_WRRWEIGHTS_6_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_7 0x168840 +#define QM_REG_WRRWEIGHTS_7_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_8 0x168844 +#define QM_REG_WRRWEIGHTS_8_SIZE 1 +/* [RW 32] Wrr weights */ +#define QM_REG_WRRWEIGHTS_9 0x168848 +#define QM_REG_WRRWEIGHTS_9_SIZE 1 +/* [RW 22] Number of free element in the free list of T2 entries - port 0. */ +#define SRC_REG_COUNTFREE0 0x40500 +/* [WB 64] First free element in the free list of T2 entries - port 0. */ +#define SRC_REG_FIRSTFREE0 0x40510 +#define SRC_REG_KEYRSS0_0 0x40408 +#define SRC_REG_KEYRSS1_9 0x40454 +/* [WB 64] Last free element in the free list of T2 entries - port 0. */ +#define SRC_REG_LASTFREE0 0x40530 +/* [RW 5] The number of hash bits used for the search (h); Values can be 8 + to 24. */ +#define SRC_REG_NUMBER_HASH_BITS0 0x40400 +/* [RW 1] Reset internal state machines. */ +#define SRC_REG_SOFT_RST 0x4049c +/* [R 1] Interrupt register #0 read */ +#define SRC_REG_SRC_INT_STS 0x404ac +/* [RW 3] Parity mask register #0 read/write */ +#define SRC_REG_SRC_PRTY_MASK 0x404c8 +/* [R 4] Used to read the value of the XX protection CAM occupancy counter. */ +#define TCM_REG_CAM_OCCUP 0x5017c +/* [RW 1] CDU AG read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define TCM_REG_CDU_AG_RD_IFEN 0x50034 +/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input + are disregarded; all other signals are treated as usual; if 1 - normal + activity. */ +#define TCM_REG_CDU_AG_WR_IFEN 0x50030 +/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define TCM_REG_CDU_SM_RD_IFEN 0x5003c +/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid + input is disregarded; all other signals are treated as usual; if 1 - + normal activity. */ +#define TCM_REG_CDU_SM_WR_IFEN 0x50038 +/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 1 at start-up. */ +#define TCM_REG_CFC_INIT_CRD 0x50204 +/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define TCM_REG_CP_WEIGHT 0x500c0 +/* [RW 1] Input csem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define TCM_REG_CSEM_IFEN 0x5002c +/* [RC 1] Message length mismatch (relative to last indication) at the In#9 + interface. */ +#define TCM_REG_CSEM_LENGTH_MIS 0x50174 +/* [RW 8] The Event ID in case of ErrorFlg is set in the input message. */ +#define TCM_REG_ERR_EVNT_ID 0x500a0 +/* [RW 28] The CM erroneous header for QM and Timers formatting. */ +#define TCM_REG_ERR_TCM_HDR 0x5009c +/* [RW 8] The Event ID for Timers expiration. */ +#define TCM_REG_EXPR_EVNT_ID 0x500a4 +/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define TCM_REG_FIC0_INIT_CRD 0x5020c +/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define TCM_REG_FIC1_INIT_CRD 0x50210 +/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1 + - strict priority defined by ~tcm_registers_gr_ag_pr.gr_ag_pr; + ~tcm_registers_gr_ld0_pr.gr_ld0_pr and + ~tcm_registers_gr_ld1_pr.gr_ld1_pr. */ +#define TCM_REG_GR_ARB_TYPE 0x50114 +/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Store channel is the + compliment of the other 3 groups. */ +#define TCM_REG_GR_LD0_PR 0x5011c +/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Store channel is the + compliment of the other 3 groups. */ +#define TCM_REG_GR_LD1_PR 0x50120 +/* [RW 4] The number of double REG-pairs; loaded from the STORM context and + sent to STORM; for a specific connection type. The double REG-pairs are + used to align to STORM context row size of 128 bits. The offset of these + data in the STORM context is always 0. Index _i stands for the connection + type (one of 16). */ +#define TCM_REG_N_SM_CTX_LD_0 0x50050 +#define TCM_REG_N_SM_CTX_LD_1 0x50054 +#define TCM_REG_N_SM_CTX_LD_10 0x50078 +#define TCM_REG_N_SM_CTX_LD_11 0x5007c +#define TCM_REG_N_SM_CTX_LD_12 0x50080 +#define TCM_REG_N_SM_CTX_LD_13 0x50084 +#define TCM_REG_N_SM_CTX_LD_14 0x50088 +#define TCM_REG_N_SM_CTX_LD_15 0x5008c +#define TCM_REG_N_SM_CTX_LD_2 0x50058 +#define TCM_REG_N_SM_CTX_LD_3 0x5005c +#define TCM_REG_N_SM_CTX_LD_4 0x50060 +/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_PBF_IFEN 0x50024 +/* [RC 1] Message length mismatch (relative to last indication) at the In#7 + interface. */ +#define TCM_REG_PBF_LENGTH_MIS 0x5016c +/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define TCM_REG_PBF_WEIGHT 0x500b4 +/* [RW 6] The physical queue number 0 per port index. */ +#define TCM_REG_PHYS_QNUM0_0 0x500e0 +#define TCM_REG_PHYS_QNUM0_1 0x500e4 +/* [RW 6] The physical queue number 1 per port index. */ +#define TCM_REG_PHYS_QNUM1_0 0x500e8 +/* [RW 1] Input prs Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_PRS_IFEN 0x50020 +/* [RC 1] Message length mismatch (relative to last indication) at the In#6 + interface. */ +#define TCM_REG_PRS_LENGTH_MIS 0x50168 +/* [RW 3] The weight of the input prs in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define TCM_REG_PRS_WEIGHT 0x500b0 +/* [RW 8] The Event ID for Timers formatting in case of stop done. */ +#define TCM_REG_STOP_EVNT_ID 0x500a8 +/* [RC 1] Message length mismatch (relative to last indication) at the STORM + interface. */ +#define TCM_REG_STORM_LENGTH_MIS 0x50160 +/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define TCM_REG_STORM_TCM_IFEN 0x50010 +/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TCM_CFC_IFEN 0x50040 +/* [RW 11] Interrupt mask register #0 read/write */ +#define TCM_REG_TCM_INT_MASK 0x501dc +/* [R 11] Interrupt register #0 read */ +#define TCM_REG_TCM_INT_STS 0x501d0 +/* [RW 3] The size of AG context region 0 in REG-pairs. Designates the MS + REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). + Is used to determine the number of the AG context REG-pairs written back; + when the input message Reg1WbFlg isn't set. */ +#define TCM_REG_TCM_REG0_SZ 0x500d8 +/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TCM_STORM0_IFEN 0x50004 +/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TCM_STORM1_IFEN 0x50008 +/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TCM_TQM_IFEN 0x5000c +/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */ +#define TCM_REG_TCM_TQM_USE_Q 0x500d4 +/* [RW 28] The CM header for Timers expiration command. */ +#define TCM_REG_TM_TCM_HDR 0x50098 +/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define TCM_REG_TM_TCM_IFEN 0x5001c +/* [RW 6] QM output initial credit. Max credit available - 32.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 32 at start-up. */ +#define TCM_REG_TQM_INIT_CRD 0x5021c +/* [RW 28] The CM header value for QM request (primary). */ +#define TCM_REG_TQM_TCM_HDR_P 0x50090 +/* [RW 28] The CM header value for QM request (secondary). */ +#define TCM_REG_TQM_TCM_HDR_S 0x50094 +/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TQM_TCM_IFEN 0x50014 +/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define TCM_REG_TSDM_IFEN 0x50018 +/* [RC 1] Message length mismatch (relative to last indication) at the SDM + interface. */ +#define TCM_REG_TSDM_LENGTH_MIS 0x50164 +/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define TCM_REG_TSDM_WEIGHT 0x500c4 +/* [RW 1] Input usem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define TCM_REG_USEM_IFEN 0x50028 +/* [RC 1] Message length mismatch (relative to last indication) at the In#8 + interface. */ +#define TCM_REG_USEM_LENGTH_MIS 0x50170 +/* [RW 21] Indirect access to the descriptor table of the XX protection + mechanism. The fields are: [5:0] - length of the message; 15:6] - message + pointer; 20:16] - next pointer. */ +#define TCM_REG_XX_DESCR_TABLE 0x50280 +/* [R 6] Use to read the value of XX protection Free counter. */ +#define TCM_REG_XX_FREE 0x50178 +/* [RW 6] Initial value for the credit counter; responsible for fulfilling + of the Input Stage XX protection buffer by the XX protection pending + messages. Max credit available - 127.Write writes the initial credit + value; read returns the current value of the credit counter. Must be + initialized to 19 at start-up. */ +#define TCM_REG_XX_INIT_CRD 0x50220 +/* [RW 6] Maximum link list size (messages locked) per connection in the XX + protection. */ +#define TCM_REG_XX_MAX_LL_SZ 0x50044 +/* [RW 6] The maximum number of pending messages; which may be stored in XX + protection. ~tcm_registers_xx_free.xx_free is read on read. */ +#define TCM_REG_XX_MSG_NUM 0x50224 +/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */ +#define TCM_REG_XX_OVFL_EVNT_ID 0x50048 +/* [RW 16] Indirect access to the XX table of the XX protection mechanism. + The fields are:[4:0] - tail pointer; [10:5] - Link List size; 15:11] - + header pointer. */ +#define TCM_REG_XX_TABLE 0x50240 +/* [RW 4] Load value for for cfc ac credit cnt. */ +#define TM_REG_CFC_AC_CRDCNT_VAL 0x164208 +/* [RW 4] Load value for cfc cld credit cnt. */ +#define TM_REG_CFC_CLD_CRDCNT_VAL 0x164210 +/* [RW 8] Client0 context region. */ +#define TM_REG_CL0_CONT_REGION 0x164030 +/* [RW 8] Client1 context region. */ +#define TM_REG_CL1_CONT_REGION 0x164034 +/* [RW 8] Client2 context region. */ +#define TM_REG_CL2_CONT_REGION 0x164038 +/* [RW 2] Client in High priority client number. */ +#define TM_REG_CLIN_PRIOR0_CLIENT 0x164024 +/* [RW 4] Load value for clout0 cred cnt. */ +#define TM_REG_CLOUT_CRDCNT0_VAL 0x164220 +/* [RW 4] Load value for clout1 cred cnt. */ +#define TM_REG_CLOUT_CRDCNT1_VAL 0x164228 +/* [RW 4] Load value for clout2 cred cnt. */ +#define TM_REG_CLOUT_CRDCNT2_VAL 0x164230 +/* [RW 1] Enable client0 input. */ +#define TM_REG_EN_CL0_INPUT 0x164008 +/* [RW 1] Enable client1 input. */ +#define TM_REG_EN_CL1_INPUT 0x16400c +/* [RW 1] Enable client2 input. */ +#define TM_REG_EN_CL2_INPUT 0x164010 +/* [RW 1] Enable real time counter. */ +#define TM_REG_EN_REAL_TIME_CNT 0x1640d8 +/* [RW 1] Enable for Timers state machines. */ +#define TM_REG_EN_TIMERS 0x164000 +/* [RW 4] Load value for expiration credit cnt. CFC max number of + outstanding load requests for timers (expiration) context loading. */ +#define TM_REG_EXP_CRDCNT_VAL 0x164238 +/* [RW 18] Linear0 Max active cid. */ +#define TM_REG_LIN0_MAX_ACTIVE_CID 0x164048 +/* [WB 64] Linear0 phy address. */ +#define TM_REG_LIN0_PHY_ADDR 0x164270 +/* [RW 24] Linear0 array scan timeout. */ +#define TM_REG_LIN0_SCAN_TIME 0x16403c +/* [WB 64] Linear1 phy address. */ +#define TM_REG_LIN1_PHY_ADDR 0x164280 +/* [RW 6] Linear timer set_clear fifo threshold. */ +#define TM_REG_LIN_SETCLR_FIFO_ALFULL_THR 0x164070 +/* [RW 2] Load value for pci arbiter credit cnt. */ +#define TM_REG_PCIARB_CRDCNT_VAL 0x164260 +/* [RW 1] Timer software reset - active high. */ +#define TM_REG_TIMER_SOFT_RST 0x164004 +/* [RW 20] The amount of hardware cycles for each timer tick. */ +#define TM_REG_TIMER_TICK_SIZE 0x16401c +/* [RW 8] Timers Context region. */ +#define TM_REG_TM_CONTEXT_REGION 0x164044 +/* [RW 1] Interrupt mask register #0 read/write */ +#define TM_REG_TM_INT_MASK 0x1640fc +/* [R 1] Interrupt register #0 read */ +#define TM_REG_TM_INT_STS 0x1640f0 +/* [RW 8] The event id for aggregated interrupt 0 */ +#define TSDM_REG_AGG_INT_EVENT_0 0x42038 +/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ +#define TSDM_REG_CFC_RSP_START_ADDR 0x42008 +/* [RW 16] The maximum value of the competion counter #0 */ +#define TSDM_REG_CMP_COUNTER_MAX0 0x4201c +/* [RW 16] The maximum value of the competion counter #1 */ +#define TSDM_REG_CMP_COUNTER_MAX1 0x42020 +/* [RW 16] The maximum value of the competion counter #2 */ +#define TSDM_REG_CMP_COUNTER_MAX2 0x42024 +/* [RW 16] The maximum value of the competion counter #3 */ +#define TSDM_REG_CMP_COUNTER_MAX3 0x42028 +/* [RW 13] The start address in the internal RAM for the completion + counters. */ +#define TSDM_REG_CMP_COUNTER_START_ADDR 0x4200c +#define TSDM_REG_ENABLE_IN1 0x42238 +#define TSDM_REG_ENABLE_IN2 0x4223c +#define TSDM_REG_ENABLE_OUT1 0x42240 +#define TSDM_REG_ENABLE_OUT2 0x42244 +/* [RW 4] The initial number of messages that can be sent to the pxp control + interface without receiving any ACK. */ +#define TSDM_REG_INIT_CREDIT_PXP_CTRL 0x424bc +/* [ST 32] The number of ACK after placement messages received */ +#define TSDM_REG_NUM_OF_ACK_AFTER_PLACE 0x4227c +/* [ST 32] The number of packet end messages received from the parser */ +#define TSDM_REG_NUM_OF_PKT_END_MSG 0x42274 +/* [ST 32] The number of requests received from the pxp async if */ +#define TSDM_REG_NUM_OF_PXP_ASYNC_REQ 0x42278 +/* [ST 32] The number of commands received in queue 0 */ +#define TSDM_REG_NUM_OF_Q0_CMD 0x42248 +/* [ST 32] The number of commands received in queue 10 */ +#define TSDM_REG_NUM_OF_Q10_CMD 0x4226c +/* [ST 32] The number of commands received in queue 11 */ +#define TSDM_REG_NUM_OF_Q11_CMD 0x42270 +/* [ST 32] The number of commands received in queue 1 */ +#define TSDM_REG_NUM_OF_Q1_CMD 0x4224c +/* [ST 32] The number of commands received in queue 3 */ +#define TSDM_REG_NUM_OF_Q3_CMD 0x42250 +/* [ST 32] The number of commands received in queue 4 */ +#define TSDM_REG_NUM_OF_Q4_CMD 0x42254 +/* [ST 32] The number of commands received in queue 5 */ +#define TSDM_REG_NUM_OF_Q5_CMD 0x42258 +/* [ST 32] The number of commands received in queue 6 */ +#define TSDM_REG_NUM_OF_Q6_CMD 0x4225c +/* [ST 32] The number of commands received in queue 7 */ +#define TSDM_REG_NUM_OF_Q7_CMD 0x42260 +/* [ST 32] The number of commands received in queue 8 */ +#define TSDM_REG_NUM_OF_Q8_CMD 0x42264 +/* [ST 32] The number of commands received in queue 9 */ +#define TSDM_REG_NUM_OF_Q9_CMD 0x42268 +/* [RW 13] The start address in the internal RAM for the packet end message */ +#define TSDM_REG_PCK_END_MSG_START_ADDR 0x42014 +/* [RW 13] The start address in the internal RAM for queue counters */ +#define TSDM_REG_Q_COUNTER_START_ADDR 0x42010 +/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */ +#define TSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY 0x42548 +/* [R 1] parser fifo empty in sdm_sync block */ +#define TSDM_REG_SYNC_PARSER_EMPTY 0x42550 +/* [R 1] parser serial fifo empty in sdm_sync block */ +#define TSDM_REG_SYNC_SYNC_EMPTY 0x42558 +/* [RW 32] Tick for timer counter. Applicable only when + ~tsdm_registers_timer_tick_enable.timer_tick_enable =1 */ +#define TSDM_REG_TIMER_TICK 0x42000 +/* [RW 32] Interrupt mask register #0 read/write */ +#define TSDM_REG_TSDM_INT_MASK_0 0x4229c +#define TSDM_REG_TSDM_INT_MASK_1 0x422ac +/* [RW 11] Parity mask register #0 read/write */ +#define TSDM_REG_TSDM_PRTY_MASK 0x422bc +/* [RW 5] The number of time_slots in the arbitration cycle */ +#define TSEM_REG_ARB_CYCLE_SIZE 0x180034 +/* [RW 3] The source that is associated with arbitration element 0. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2 */ +#define TSEM_REG_ARB_ELEMENT0 0x180020 +/* [RW 3] The source that is associated with arbitration element 1. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~tsem_registers_arb_element0.arb_element0 */ +#define TSEM_REG_ARB_ELEMENT1 0x180024 +/* [RW 3] The source that is associated with arbitration element 2. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~tsem_registers_arb_element0.arb_element0 + and ~tsem_registers_arb_element1.arb_element1 */ +#define TSEM_REG_ARB_ELEMENT2 0x180028 +/* [RW 3] The source that is associated with arbitration element 3. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2.Could + not be equal to register ~tsem_registers_arb_element0.arb_element0 and + ~tsem_registers_arb_element1.arb_element1 and + ~tsem_registers_arb_element2.arb_element2 */ +#define TSEM_REG_ARB_ELEMENT3 0x18002c +/* [RW 3] The source that is associated with arbitration element 4. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~tsem_registers_arb_element0.arb_element0 + and ~tsem_registers_arb_element1.arb_element1 and + ~tsem_registers_arb_element2.arb_element2 and + ~tsem_registers_arb_element3.arb_element3 */ +#define TSEM_REG_ARB_ELEMENT4 0x180030 +#define TSEM_REG_ENABLE_IN 0x1800a4 +#define TSEM_REG_ENABLE_OUT 0x1800a8 +/* [RW 32] This address space contains all registers and memories that are + placed in SEM_FAST block. The SEM_FAST registers are described in + appendix B. In order to access the SEM_FAST registers the base address + TSEM_REGISTERS_FAST_MEMORY (Offset: 0x1a0000) should be added to each + SEM_FAST register offset. */ +#define TSEM_REG_FAST_MEMORY 0x1a0000 +/* [RW 1] Disables input messages from FIC0 May be updated during run_time + by the microcode */ +#define TSEM_REG_FIC0_DISABLE 0x180224 +/* [RW 1] Disables input messages from FIC1 May be updated during run_time + by the microcode */ +#define TSEM_REG_FIC1_DISABLE 0x180234 +/* [RW 15] Interrupt table Read and write access to it is not possible in + the middle of the work */ +#define TSEM_REG_INT_TABLE 0x180400 +/* [ST 24] Statistics register. The number of messages that entered through + FIC0 */ +#define TSEM_REG_MSG_NUM_FIC0 0x180000 +/* [ST 24] Statistics register. The number of messages that entered through + FIC1 */ +#define TSEM_REG_MSG_NUM_FIC1 0x180004 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC0 */ +#define TSEM_REG_MSG_NUM_FOC0 0x180008 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC1 */ +#define TSEM_REG_MSG_NUM_FOC1 0x18000c +/* [ST 24] Statistics register. The number of messages that were sent to + FOC2 */ +#define TSEM_REG_MSG_NUM_FOC2 0x180010 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC3 */ +#define TSEM_REG_MSG_NUM_FOC3 0x180014 +/* [RW 1] Disables input messages from the passive buffer May be updated + during run_time by the microcode */ +#define TSEM_REG_PAS_DISABLE 0x18024c +/* [WB 128] Debug only. Passive buffer memory */ +#define TSEM_REG_PASSIVE_BUFFER 0x181000 +/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */ +#define TSEM_REG_PRAM 0x1c0000 +/* [R 8] Valid sleeping threads indication have bit per thread */ +#define TSEM_REG_SLEEP_THREADS_VALID 0x18026c +/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */ +#define TSEM_REG_SLOW_EXT_STORE_EMPTY 0x1802a0 +/* [RW 8] List of free threads . There is a bit per thread. */ +#define TSEM_REG_THREADS_LIST 0x1802e4 +/* [RW 3] The arbitration scheme of time_slot 0 */ +#define TSEM_REG_TS_0_AS 0x180038 +/* [RW 3] The arbitration scheme of time_slot 10 */ +#define TSEM_REG_TS_10_AS 0x180060 +/* [RW 3] The arbitration scheme of time_slot 11 */ +#define TSEM_REG_TS_11_AS 0x180064 +/* [RW 3] The arbitration scheme of time_slot 12 */ +#define TSEM_REG_TS_12_AS 0x180068 +/* [RW 3] The arbitration scheme of time_slot 13 */ +#define TSEM_REG_TS_13_AS 0x18006c +/* [RW 3] The arbitration scheme of time_slot 14 */ +#define TSEM_REG_TS_14_AS 0x180070 +/* [RW 3] The arbitration scheme of time_slot 15 */ +#define TSEM_REG_TS_15_AS 0x180074 +/* [RW 3] The arbitration scheme of time_slot 16 */ +#define TSEM_REG_TS_16_AS 0x180078 +/* [RW 3] The arbitration scheme of time_slot 17 */ +#define TSEM_REG_TS_17_AS 0x18007c +/* [RW 3] The arbitration scheme of time_slot 18 */ +#define TSEM_REG_TS_18_AS 0x180080 +/* [RW 3] The arbitration scheme of time_slot 1 */ +#define TSEM_REG_TS_1_AS 0x18003c +/* [RW 3] The arbitration scheme of time_slot 2 */ +#define TSEM_REG_TS_2_AS 0x180040 +/* [RW 3] The arbitration scheme of time_slot 3 */ +#define TSEM_REG_TS_3_AS 0x180044 +/* [RW 3] The arbitration scheme of time_slot 4 */ +#define TSEM_REG_TS_4_AS 0x180048 +/* [RW 3] The arbitration scheme of time_slot 5 */ +#define TSEM_REG_TS_5_AS 0x18004c +/* [RW 3] The arbitration scheme of time_slot 6 */ +#define TSEM_REG_TS_6_AS 0x180050 +/* [RW 3] The arbitration scheme of time_slot 7 */ +#define TSEM_REG_TS_7_AS 0x180054 +/* [RW 3] The arbitration scheme of time_slot 8 */ +#define TSEM_REG_TS_8_AS 0x180058 +/* [RW 3] The arbitration scheme of time_slot 9 */ +#define TSEM_REG_TS_9_AS 0x18005c +/* [RW 32] Interrupt mask register #0 read/write */ +#define TSEM_REG_TSEM_INT_MASK_0 0x180100 +#define TSEM_REG_TSEM_INT_MASK_1 0x180110 +/* [RW 32] Parity mask register #0 read/write */ +#define TSEM_REG_TSEM_PRTY_MASK_0 0x180120 +#define TSEM_REG_TSEM_PRTY_MASK_1 0x180130 +/* [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 + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define UCM_REG_CDU_AG_RD_IFEN 0xe0038 +/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input + are disregarded; all other signals are treated as usual; if 1 - normal + activity. */ +#define UCM_REG_CDU_AG_WR_IFEN 0xe0034 +/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define UCM_REG_CDU_SM_RD_IFEN 0xe0040 +/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid + input is disregarded; all other signals are treated as usual; if 1 - + normal activity. */ +#define UCM_REG_CDU_SM_WR_IFEN 0xe003c +/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 1 at start-up. */ +#define UCM_REG_CFC_INIT_CRD 0xe0204 +/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define UCM_REG_CP_WEIGHT 0xe00c4 +/* [RW 1] Input csem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_CSEM_IFEN 0xe0028 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the csem interface is detected. */ +#define UCM_REG_CSEM_LENGTH_MIS 0xe0160 +/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define UCM_REG_CSEM_WEIGHT 0xe00b8 +/* [RW 1] Input dorq Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_DORQ_IFEN 0xe0030 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the dorq interface is detected. */ +#define UCM_REG_DORQ_LENGTH_MIS 0xe0168 +/* [RW 8] The Event ID in case ErrorFlg input message bit is set. */ +#define UCM_REG_ERR_EVNT_ID 0xe00a4 +/* [RW 28] The CM erroneous header for QM and Timers formatting. */ +#define UCM_REG_ERR_UCM_HDR 0xe00a0 +/* [RW 8] The Event ID for Timers expiration. */ +#define UCM_REG_EXPR_EVNT_ID 0xe00a8 +/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define UCM_REG_FIC0_INIT_CRD 0xe020c +/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define UCM_REG_FIC1_INIT_CRD 0xe0210 +/* [RW 1] Arbitration between Input Arbiter groups: 0 - fair Round-Robin; 1 + - strict priority defined by ~ucm_registers_gr_ag_pr.gr_ag_pr; + ~ucm_registers_gr_ld0_pr.gr_ld0_pr and + ~ucm_registers_gr_ld1_pr.gr_ld1_pr. */ +#define UCM_REG_GR_ARB_TYPE 0xe0144 +/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Store channel group is + compliment to the others. */ +#define UCM_REG_GR_LD0_PR 0xe014c +/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Store channel group is + compliment to the others. */ +#define UCM_REG_GR_LD1_PR 0xe0150 +/* [RW 2] The queue index for invalidate counter flag decision. */ +#define UCM_REG_INV_CFLG_Q 0xe00e4 +/* [RW 5] The number of double REG-pairs; loaded from the STORM context and + sent to STORM; for a specific connection type. the double REG-pairs are + used in order to align to STORM context row size of 128 bits. The offset + of these data in the STORM context is always 0. Index _i stands for the + connection type (one of 16). */ +#define UCM_REG_N_SM_CTX_LD_0 0xe0054 +#define UCM_REG_N_SM_CTX_LD_1 0xe0058 +#define UCM_REG_N_SM_CTX_LD_10 0xe007c +#define UCM_REG_N_SM_CTX_LD_11 0xe0080 +#define UCM_REG_N_SM_CTX_LD_12 0xe0084 +#define UCM_REG_N_SM_CTX_LD_13 0xe0088 +#define UCM_REG_N_SM_CTX_LD_14 0xe008c +#define UCM_REG_N_SM_CTX_LD_15 0xe0090 +#define UCM_REG_N_SM_CTX_LD_2 0xe005c +#define UCM_REG_N_SM_CTX_LD_3 0xe0060 +#define UCM_REG_N_SM_CTX_LD_4 0xe0064 +/* [RW 6] The physical queue number 0 per port index (CID[23]) */ +#define UCM_REG_PHYS_QNUM0_0 0xe0110 +#define UCM_REG_PHYS_QNUM0_1 0xe0114 +/* [RW 6] The physical queue number 1 per port index (CID[23]) */ +#define UCM_REG_PHYS_QNUM1_0 0xe0118 +#define UCM_REG_PHYS_QNUM1_1 0xe011c +/* [RW 8] The Event ID for Timers formatting in case of stop done. */ +#define UCM_REG_STOP_EVNT_ID 0xe00ac +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the STORM interface is detected. */ +#define UCM_REG_STORM_LENGTH_MIS 0xe0154 +/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_STORM_UCM_IFEN 0xe0010 +/* [RW 4] Timers output initial credit. Max credit available - 15.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 4 at start-up. */ +#define UCM_REG_TM_INIT_CRD 0xe021c +/* [RW 28] The CM header for Timers expiration command. */ +#define UCM_REG_TM_UCM_HDR 0xe009c +/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_TM_UCM_IFEN 0xe001c +/* [RW 1] Input tsem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_TSEM_IFEN 0xe0024 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the tsem interface is detected. */ +#define UCM_REG_TSEM_LENGTH_MIS 0xe015c +/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define UCM_REG_TSEM_WEIGHT 0xe00b4 +/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_UCM_CFC_IFEN 0xe0044 +/* [RW 11] Interrupt mask register #0 read/write */ +#define UCM_REG_UCM_INT_MASK 0xe01d4 +/* [R 11] Interrupt register #0 read */ +#define UCM_REG_UCM_INT_STS 0xe01c8 +/* [RW 2] The size of AG context region 0 in REG-pairs. Designates the MS + REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). + Is used to determine the number of the AG context REG-pairs written back; + when the Reg1WbFlg isn't set. */ +#define UCM_REG_UCM_REG0_SZ 0xe00dc +/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_UCM_STORM0_IFEN 0xe0004 +/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_UCM_STORM1_IFEN 0xe0008 +/* [RW 1] CM - Timers Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_UCM_TM_IFEN 0xe0020 +/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_UCM_UQM_IFEN 0xe000c +/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */ +#define UCM_REG_UCM_UQM_USE_Q 0xe00d8 +/* [RW 6] QM output initial credit. Max credit available - 32.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 32 at start-up. */ +#define UCM_REG_UQM_INIT_CRD 0xe0220 +/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0 + stands for weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define UCM_REG_UQM_P_WEIGHT 0xe00cc +/* [RW 28] The CM header value for QM request (primary). */ +#define UCM_REG_UQM_UCM_HDR_P 0xe0094 +/* [RW 28] The CM header value for QM request (secondary). */ +#define UCM_REG_UQM_UCM_HDR_S 0xe0098 +/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_UQM_UCM_IFEN 0xe0014 +/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define UCM_REG_USDM_IFEN 0xe0018 +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the SDM interface is detected. */ +#define UCM_REG_USDM_LENGTH_MIS 0xe0158 +/* [RW 1] Input xsem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define UCM_REG_XSEM_IFEN 0xe002c +/* [RC 1] Set when the message length mismatch (relative to last indication) + at the xsem interface isdetected. */ +#define UCM_REG_XSEM_LENGTH_MIS 0xe0164 +/* [RW 20] Indirect access to the descriptor table of the XX protection + mechanism. The fields are:[5:0] - message length; 14:6] - message + pointer; 19:15] - next pointer. */ +#define UCM_REG_XX_DESCR_TABLE 0xe0280 +/* [R 6] Use to read the XX protection Free counter. */ +#define UCM_REG_XX_FREE 0xe016c +/* [RW 6] Initial value for the credit counter; responsible for fulfilling + of the Input Stage XX protection buffer by the XX protection pending + messages. Write writes the initial credit value; read returns the current + value of the credit counter. Must be initialized to 12 at start-up. */ +#define UCM_REG_XX_INIT_CRD 0xe0224 +/* [RW 6] The maximum number of pending messages; which may be stored in XX + protection. ~ucm_registers_xx_free.xx_free read on read. */ +#define UCM_REG_XX_MSG_NUM 0xe0228 +/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */ +#define UCM_REG_XX_OVFL_EVNT_ID 0xe004c +/* [RW 16] Indirect access to the XX table of the XX protection mechanism. + The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] - + header pointer. */ +#define UCM_REG_XX_TABLE 0xe0300 +/* [RW 8] The event id for aggregated interrupt 0 */ +#define USDM_REG_AGG_INT_EVENT_0 0xc4038 +#define USDM_REG_AGG_INT_EVENT_1 0xc403c +#define USDM_REG_AGG_INT_EVENT_10 0xc4060 +#define USDM_REG_AGG_INT_EVENT_11 0xc4064 +#define USDM_REG_AGG_INT_EVENT_12 0xc4068 +#define USDM_REG_AGG_INT_EVENT_13 0xc406c +#define USDM_REG_AGG_INT_EVENT_14 0xc4070 +#define USDM_REG_AGG_INT_EVENT_15 0xc4074 +#define USDM_REG_AGG_INT_EVENT_16 0xc4078 +#define USDM_REG_AGG_INT_EVENT_17 0xc407c +#define USDM_REG_AGG_INT_EVENT_18 0xc4080 +#define USDM_REG_AGG_INT_EVENT_19 0xc4084 +/* [RW 1] For each aggregated interrupt index whether the mode is normal (0) + or auto-mask-mode (1) */ +#define USDM_REG_AGG_INT_MODE_0 0xc41b8 +#define USDM_REG_AGG_INT_MODE_1 0xc41bc +#define USDM_REG_AGG_INT_MODE_10 0xc41e0 +#define USDM_REG_AGG_INT_MODE_11 0xc41e4 +#define USDM_REG_AGG_INT_MODE_12 0xc41e8 +#define USDM_REG_AGG_INT_MODE_13 0xc41ec +#define USDM_REG_AGG_INT_MODE_14 0xc41f0 +#define USDM_REG_AGG_INT_MODE_15 0xc41f4 +#define USDM_REG_AGG_INT_MODE_16 0xc41f8 +#define USDM_REG_AGG_INT_MODE_17 0xc41fc +#define USDM_REG_AGG_INT_MODE_18 0xc4200 +#define USDM_REG_AGG_INT_MODE_19 0xc4204 +/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ +#define USDM_REG_CFC_RSP_START_ADDR 0xc4008 +/* [RW 16] The maximum value of the competion counter #0 */ +#define USDM_REG_CMP_COUNTER_MAX0 0xc401c +/* [RW 16] The maximum value of the competion counter #1 */ +#define USDM_REG_CMP_COUNTER_MAX1 0xc4020 +/* [RW 16] The maximum value of the competion counter #2 */ +#define USDM_REG_CMP_COUNTER_MAX2 0xc4024 +/* [RW 16] The maximum value of the competion counter #3 */ +#define USDM_REG_CMP_COUNTER_MAX3 0xc4028 +/* [RW 13] The start address in the internal RAM for the completion + counters. */ +#define USDM_REG_CMP_COUNTER_START_ADDR 0xc400c +#define USDM_REG_ENABLE_IN1 0xc4238 +#define USDM_REG_ENABLE_IN2 0xc423c +#define USDM_REG_ENABLE_OUT1 0xc4240 +#define USDM_REG_ENABLE_OUT2 0xc4244 +/* [RW 4] The initial number of messages that can be sent to the pxp control + interface without receiving any ACK. */ +#define USDM_REG_INIT_CREDIT_PXP_CTRL 0xc44c0 +/* [ST 32] The number of ACK after placement messages received */ +#define USDM_REG_NUM_OF_ACK_AFTER_PLACE 0xc4280 +/* [ST 32] The number of packet end messages received from the parser */ +#define USDM_REG_NUM_OF_PKT_END_MSG 0xc4278 +/* [ST 32] The number of requests received from the pxp async if */ +#define USDM_REG_NUM_OF_PXP_ASYNC_REQ 0xc427c +/* [ST 32] The number of commands received in queue 0 */ +#define USDM_REG_NUM_OF_Q0_CMD 0xc4248 +/* [ST 32] The number of commands received in queue 10 */ +#define USDM_REG_NUM_OF_Q10_CMD 0xc4270 +/* [ST 32] The number of commands received in queue 11 */ +#define USDM_REG_NUM_OF_Q11_CMD 0xc4274 +/* [ST 32] The number of commands received in queue 1 */ +#define USDM_REG_NUM_OF_Q1_CMD 0xc424c +/* [ST 32] The number of commands received in queue 2 */ +#define USDM_REG_NUM_OF_Q2_CMD 0xc4250 +/* [ST 32] The number of commands received in queue 3 */ +#define USDM_REG_NUM_OF_Q3_CMD 0xc4254 +/* [ST 32] The number of commands received in queue 4 */ +#define USDM_REG_NUM_OF_Q4_CMD 0xc4258 +/* [ST 32] The number of commands received in queue 5 */ +#define USDM_REG_NUM_OF_Q5_CMD 0xc425c +/* [ST 32] The number of commands received in queue 6 */ +#define USDM_REG_NUM_OF_Q6_CMD 0xc4260 +/* [ST 32] The number of commands received in queue 7 */ +#define USDM_REG_NUM_OF_Q7_CMD 0xc4264 +/* [ST 32] The number of commands received in queue 8 */ +#define USDM_REG_NUM_OF_Q8_CMD 0xc4268 +/* [ST 32] The number of commands received in queue 9 */ +#define USDM_REG_NUM_OF_Q9_CMD 0xc426c +/* [RW 13] The start address in the internal RAM for the packet end message */ +#define USDM_REG_PCK_END_MSG_START_ADDR 0xc4014 +/* [RW 13] The start address in the internal RAM for queue counters */ +#define USDM_REG_Q_COUNTER_START_ADDR 0xc4010 +/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */ +#define USDM_REG_RSP_PXP_CTRL_RDATA_EMPTY 0xc4550 +/* [R 1] parser fifo empty in sdm_sync block */ +#define USDM_REG_SYNC_PARSER_EMPTY 0xc4558 +/* [R 1] parser serial fifo empty in sdm_sync block */ +#define USDM_REG_SYNC_SYNC_EMPTY 0xc4560 +/* [RW 32] Tick for timer counter. Applicable only when + ~usdm_registers_timer_tick_enable.timer_tick_enable =1 */ +#define USDM_REG_TIMER_TICK 0xc4000 +/* [RW 32] Interrupt mask register #0 read/write */ +#define USDM_REG_USDM_INT_MASK_0 0xc42a0 +#define USDM_REG_USDM_INT_MASK_1 0xc42b0 +/* [RW 11] Parity mask register #0 read/write */ +#define USDM_REG_USDM_PRTY_MASK 0xc42c0 +/* [RW 5] The number of time_slots in the arbitration cycle */ +#define USEM_REG_ARB_CYCLE_SIZE 0x300034 +/* [RW 3] The source that is associated with arbitration element 0. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2 */ +#define USEM_REG_ARB_ELEMENT0 0x300020 +/* [RW 3] The source that is associated with arbitration element 1. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~usem_registers_arb_element0.arb_element0 */ +#define USEM_REG_ARB_ELEMENT1 0x300024 +/* [RW 3] The source that is associated with arbitration element 2. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~usem_registers_arb_element0.arb_element0 + and ~usem_registers_arb_element1.arb_element1 */ +#define USEM_REG_ARB_ELEMENT2 0x300028 +/* [RW 3] The source that is associated with arbitration element 3. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2.Could + not be equal to register ~usem_registers_arb_element0.arb_element0 and + ~usem_registers_arb_element1.arb_element1 and + ~usem_registers_arb_element2.arb_element2 */ +#define USEM_REG_ARB_ELEMENT3 0x30002c +/* [RW 3] The source that is associated with arbitration element 4. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~usem_registers_arb_element0.arb_element0 + and ~usem_registers_arb_element1.arb_element1 and + ~usem_registers_arb_element2.arb_element2 and + ~usem_registers_arb_element3.arb_element3 */ +#define USEM_REG_ARB_ELEMENT4 0x300030 +#define USEM_REG_ENABLE_IN 0x3000a4 +#define USEM_REG_ENABLE_OUT 0x3000a8 +/* [RW 32] This address space contains all registers and memories that are + placed in SEM_FAST block. The SEM_FAST registers are described in + appendix B. In order to access the SEM_FAST registers... the base address + USEM_REGISTERS_FAST_MEMORY (Offset: 0x320000) should be added to each + SEM_FAST register offset. */ +#define USEM_REG_FAST_MEMORY 0x320000 +/* [RW 1] Disables input messages from FIC0 May be updated during run_time + by the microcode */ +#define USEM_REG_FIC0_DISABLE 0x300224 +/* [RW 1] Disables input messages from FIC1 May be updated during run_time + by the microcode */ +#define USEM_REG_FIC1_DISABLE 0x300234 +/* [RW 15] Interrupt table Read and write access to it is not possible in + the middle of the work */ +#define USEM_REG_INT_TABLE 0x300400 +/* [ST 24] Statistics register. The number of messages that entered through + FIC0 */ +#define USEM_REG_MSG_NUM_FIC0 0x300000 +/* [ST 24] Statistics register. The number of messages that entered through + FIC1 */ +#define USEM_REG_MSG_NUM_FIC1 0x300004 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC0 */ +#define USEM_REG_MSG_NUM_FOC0 0x300008 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC1 */ +#define USEM_REG_MSG_NUM_FOC1 0x30000c +/* [ST 24] Statistics register. The number of messages that were sent to + FOC2 */ +#define USEM_REG_MSG_NUM_FOC2 0x300010 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC3 */ +#define USEM_REG_MSG_NUM_FOC3 0x300014 +/* [RW 1] Disables input messages from the passive buffer May be updated + during run_time by the microcode */ +#define USEM_REG_PAS_DISABLE 0x30024c +/* [WB 128] Debug only. Passive buffer memory */ +#define USEM_REG_PASSIVE_BUFFER 0x302000 +/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */ +#define USEM_REG_PRAM 0x340000 +/* [R 16] Valid sleeping threads indication have bit per thread */ +#define USEM_REG_SLEEP_THREADS_VALID 0x30026c +/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */ +#define USEM_REG_SLOW_EXT_STORE_EMPTY 0x3002a0 +/* [RW 16] List of free threads . There is a bit per thread. */ +#define USEM_REG_THREADS_LIST 0x3002e4 +/* [RW 3] The arbitration scheme of time_slot 0 */ +#define USEM_REG_TS_0_AS 0x300038 +/* [RW 3] The arbitration scheme of time_slot 10 */ +#define USEM_REG_TS_10_AS 0x300060 +/* [RW 3] The arbitration scheme of time_slot 11 */ +#define USEM_REG_TS_11_AS 0x300064 +/* [RW 3] The arbitration scheme of time_slot 12 */ +#define USEM_REG_TS_12_AS 0x300068 +/* [RW 3] The arbitration scheme of time_slot 13 */ +#define USEM_REG_TS_13_AS 0x30006c +/* [RW 3] The arbitration scheme of time_slot 14 */ +#define USEM_REG_TS_14_AS 0x300070 +/* [RW 3] The arbitration scheme of time_slot 15 */ +#define USEM_REG_TS_15_AS 0x300074 +/* [RW 3] The arbitration scheme of time_slot 16 */ +#define USEM_REG_TS_16_AS 0x300078 +/* [RW 3] The arbitration scheme of time_slot 17 */ +#define USEM_REG_TS_17_AS 0x30007c +/* [RW 3] The arbitration scheme of time_slot 18 */ +#define USEM_REG_TS_18_AS 0x300080 +/* [RW 3] The arbitration scheme of time_slot 1 */ +#define USEM_REG_TS_1_AS 0x30003c +/* [RW 3] The arbitration scheme of time_slot 2 */ +#define USEM_REG_TS_2_AS 0x300040 +/* [RW 3] The arbitration scheme of time_slot 3 */ +#define USEM_REG_TS_3_AS 0x300044 +/* [RW 3] The arbitration scheme of time_slot 4 */ +#define USEM_REG_TS_4_AS 0x300048 +/* [RW 3] The arbitration scheme of time_slot 5 */ +#define USEM_REG_TS_5_AS 0x30004c +/* [RW 3] The arbitration scheme of time_slot 6 */ +#define USEM_REG_TS_6_AS 0x300050 +/* [RW 3] The arbitration scheme of time_slot 7 */ +#define USEM_REG_TS_7_AS 0x300054 +/* [RW 3] The arbitration scheme of time_slot 8 */ +#define USEM_REG_TS_8_AS 0x300058 +/* [RW 3] The arbitration scheme of time_slot 9 */ +#define USEM_REG_TS_9_AS 0x30005c +/* [RW 32] Interrupt mask register #0 read/write */ +#define USEM_REG_USEM_INT_MASK_0 0x300110 +#define USEM_REG_USEM_INT_MASK_1 0x300120 +/* [RW 32] Parity mask register #0 read/write */ +#define USEM_REG_USEM_PRTY_MASK_0 0x300130 +#define USEM_REG_USEM_PRTY_MASK_1 0x300140 +/* [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. */ +#define XCM_REG_AUX_CNT_FLG_Q_19 0x201b0 +/* [R 5] Used to read the XX protection CAM occupancy counter. */ +#define XCM_REG_CAM_OCCUP 0x20244 +/* [RW 1] CDU AG read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define XCM_REG_CDU_AG_RD_IFEN 0x20044 +/* [RW 1] CDU AG write Interface enable. If 0 - the request and valid input + are disregarded; all other signals are treated as usual; if 1 - normal + activity. */ +#define XCM_REG_CDU_AG_WR_IFEN 0x20040 +/* [RW 1] CDU STORM read Interface enable. If 0 - the request input is + disregarded; valid output is deasserted; all other signals are treated as + usual; if 1 - normal activity. */ +#define XCM_REG_CDU_SM_RD_IFEN 0x2004c +/* [RW 1] CDU STORM write Interface enable. If 0 - the request and valid + input is disregarded; all other signals are treated as usual; if 1 - + normal activity. */ +#define XCM_REG_CDU_SM_WR_IFEN 0x20048 +/* [RW 4] CFC output initial credit. Max credit available - 15.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 1 at start-up. */ +#define XCM_REG_CFC_INIT_CRD 0x20404 +/* [RW 3] The weight of the CP input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_CP_WEIGHT 0x200dc +/* [RW 1] Input csem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_CSEM_IFEN 0x20028 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the csem interface. */ +#define XCM_REG_CSEM_LENGTH_MIS 0x20228 +/* [RW 3] The weight of the input csem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_CSEM_WEIGHT 0x200c4 +/* [RW 1] Input dorq Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_DORQ_IFEN 0x20030 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the dorq interface. */ +#define XCM_REG_DORQ_LENGTH_MIS 0x20230 +/* [RW 8] The Event ID in case the ErrorFlg input message bit is set. */ +#define XCM_REG_ERR_EVNT_ID 0x200b0 +/* [RW 28] The CM erroneous header for QM and Timers formatting. */ +#define XCM_REG_ERR_XCM_HDR 0x200ac +/* [RW 8] The Event ID for Timers expiration. */ +#define XCM_REG_EXPR_EVNT_ID 0x200b4 +/* [RW 8] FIC0 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define XCM_REG_FIC0_INIT_CRD 0x2040c +/* [RW 8] FIC1 output initial credit. Max credit available - 255.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 64 at start-up. */ +#define XCM_REG_FIC1_INIT_CRD 0x20410 +/* [RW 8] The maximum delayed ACK counter value.Must be at least 2. Per port + value. */ +#define XCM_REG_GLB_DEL_ACK_MAX_CNT_0 0x20118 +#define XCM_REG_GLB_DEL_ACK_MAX_CNT_1 0x2011c +/* [RW 28] The delayed ACK timeout in ticks. Per port value. */ +#define XCM_REG_GLB_DEL_ACK_TMR_VAL_0 0x20108 +#define XCM_REG_GLB_DEL_ACK_TMR_VAL_1 0x2010c +/* [RW 1] Arbitratiojn between Input Arbiter groups: 0 - fair Round-Robin; 1 + - strict priority defined by ~xcm_registers_gr_ag_pr.gr_ag_pr; + ~xcm_registers_gr_ld0_pr.gr_ld0_pr and + ~xcm_registers_gr_ld1_pr.gr_ld1_pr. */ +#define XCM_REG_GR_ARB_TYPE 0x2020c +/* [RW 2] Load (FIC0) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Channel group is the + compliment of the other 3 groups. */ +#define XCM_REG_GR_LD0_PR 0x20214 +/* [RW 2] Load (FIC1) channel group priority. The lowest priority is 0; the + highest priority is 3. It is supposed that the Channel group is the + compliment of the other 3 groups. */ +#define XCM_REG_GR_LD1_PR 0x20218 +/* [RW 1] Input nig0 Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_NIG0_IFEN 0x20038 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the nig0 interface. */ +#define XCM_REG_NIG0_LENGTH_MIS 0x20238 +/* [RW 1] Input nig1 Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_NIG1_IFEN 0x2003c +/* [RC 1] Set at message length mismatch (relative to last indication) at + the nig1 interface. */ +#define XCM_REG_NIG1_LENGTH_MIS 0x2023c +/* [RW 3] The weight of the input nig1 in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_NIG1_WEIGHT 0x200d8 +/* [RW 5] The number of double REG-pairs; loaded from the STORM context and + sent to STORM; for a specific connection type. The double REG-pairs are + used in order to align to STORM context row size of 128 bits. The offset + of these data in the STORM context is always 0. Index _i stands for the + connection type (one of 16). */ +#define XCM_REG_N_SM_CTX_LD_0 0x20060 +#define XCM_REG_N_SM_CTX_LD_1 0x20064 +#define XCM_REG_N_SM_CTX_LD_10 0x20088 +#define XCM_REG_N_SM_CTX_LD_11 0x2008c +#define XCM_REG_N_SM_CTX_LD_12 0x20090 +#define XCM_REG_N_SM_CTX_LD_13 0x20094 +#define XCM_REG_N_SM_CTX_LD_14 0x20098 +#define XCM_REG_N_SM_CTX_LD_15 0x2009c +#define XCM_REG_N_SM_CTX_LD_2 0x20068 +#define XCM_REG_N_SM_CTX_LD_3 0x2006c +#define XCM_REG_N_SM_CTX_LD_4 0x20070 +/* [RW 1] Input pbf Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_PBF_IFEN 0x20034 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the pbf interface. */ +#define XCM_REG_PBF_LENGTH_MIS 0x20234 +/* [RW 3] The weight of the input pbf in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_PBF_WEIGHT 0x200d0 +/* [RW 8] The Event ID for Timers formatting in case of stop done. */ +#define XCM_REG_STOP_EVNT_ID 0x200b8 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the STORM interface. */ +#define XCM_REG_STORM_LENGTH_MIS 0x2021c +/* [RW 3] The weight of the STORM input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_STORM_WEIGHT 0x200bc +/* [RW 1] STORM - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_STORM_XCM_IFEN 0x20010 +/* [RW 4] Timers output initial credit. Max credit available - 15.Write + writes the initial credit value; read returns the current value of the + credit counter. Must be initialized to 4 at start-up. */ +#define XCM_REG_TM_INIT_CRD 0x2041c +/* [RW 28] The CM header for Timers expiration command. */ +#define XCM_REG_TM_XCM_HDR 0x200a8 +/* [RW 1] Timers - CM Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_TM_XCM_IFEN 0x2001c +/* [RW 1] Input tsem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_TSEM_IFEN 0x20024 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the tsem interface. */ +#define XCM_REG_TSEM_LENGTH_MIS 0x20224 +/* [RW 3] The weight of the input tsem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_TSEM_WEIGHT 0x200c0 +/* [RW 2] The queue index for registration on UNA greater NXT decision rule. */ +#define XCM_REG_UNA_GT_NXT_Q 0x20120 +/* [RW 1] Input usem Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_USEM_IFEN 0x2002c +/* [RC 1] Message length mismatch (relative to last indication) at the usem + interface. */ +#define XCM_REG_USEM_LENGTH_MIS 0x2022c +/* [RW 3] The weight of the input usem in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_USEM_WEIGHT 0x200c8 +/* [RW 2] DA counter command; used in case of window update doorbell.The + first index stands for the value DaEnable of that connection. The second + index stands for port number. */ +#define XCM_REG_WU_DA_CNT_CMD00 0x201d4 +/* [RW 2] DA counter command; used in case of window update doorbell.The + first index stands for the value DaEnable of that connection. The second + index stands for port number. */ +#define XCM_REG_WU_DA_CNT_CMD01 0x201d8 +/* [RW 2] DA counter command; used in case of window update doorbell.The + first index stands for the value DaEnable of that connection. The second + index stands for port number. */ +#define XCM_REG_WU_DA_CNT_CMD10 0x201dc +/* [RW 2] DA counter command; used in case of window update doorbell.The + first index stands for the value DaEnable of that connection. The second + index stands for port number. */ +#define XCM_REG_WU_DA_CNT_CMD11 0x201e0 +/* [RW 8] DA counter update value used in case of window update doorbell.The + first index stands for the value DaEnable of that connection. The second + index stands for port number. */ +#define XCM_REG_WU_DA_CNT_UPD_VAL00 0x201e4 +/* [RW 8] DA counter update value; used in case of window update + doorbell.The first index stands for the value DaEnable of that + connection. The second index stands for port number. */ +#define XCM_REG_WU_DA_CNT_UPD_VAL01 0x201e8 +/* [RW 8] DA counter update value; used in case of window update + doorbell.The first index stands for the value DaEnable of that + connection. The second index stands for port number. */ +#define XCM_REG_WU_DA_CNT_UPD_VAL10 0x201ec +/* [RW 8] DA counter update value; used in case of window update + doorbell.The first index stands for the value DaEnable of that + connection. The second index stands for port number. */ +#define XCM_REG_WU_DA_CNT_UPD_VAL11 0x201f0 +/* [RW 1] DA timer command; used in case of window update doorbell.The first + index stands for the value DaEnable of that connection. The second index + stands for port number. */ +#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00 0x201c4 +/* [RW 1] DA timer command; used in case of window update doorbell.The first + index stands for the value DaEnable of that connection. The second index + stands for port number. */ +#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01 0x201c8 +/* [RW 1] DA timer command; used in case of window update doorbell.The first + index stands for the value DaEnable of that connection. The second index + stands for port number. */ +#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10 0x201cc +/* [RW 1] DA timer command; used in case of window update doorbell.The first + index stands for the value DaEnable of that connection. The second index + stands for port number. */ +#define XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11 0x201d0 +/* [RW 1] CM - CFC Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XCM_CFC_IFEN 0x20050 +/* [RW 14] Interrupt mask register #0 read/write */ +#define XCM_REG_XCM_INT_MASK 0x202b4 +/* [R 14] Interrupt register #0 read */ +#define XCM_REG_XCM_INT_STS 0x202a8 +/* [RW 4] The size of AG context region 0 in REG-pairs. Designates the MS + REG-pair number (e.g. if region 0 is 6 REG-pairs; the value should be 5). + Is used to determine the number of the AG context REG-pairs written back; + when the Reg1WbFlg isn't set. */ +#define XCM_REG_XCM_REG0_SZ 0x200f4 +/* [RW 1] CM - STORM 0 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XCM_STORM0_IFEN 0x20004 +/* [RW 1] CM - STORM 1 Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XCM_STORM1_IFEN 0x20008 +/* [RW 1] CM - Timers Interface enable. If 0 - the valid input is + disregarded; acknowledge output is deasserted; all other signals are + treated as usual; if 1 - normal activity. */ +#define XCM_REG_XCM_TM_IFEN 0x20020 +/* [RW 1] CM - QM Interface enable. If 0 - the acknowledge input is + disregarded; valid is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XCM_XQM_IFEN 0x2000c +/* [RW 1] If set the Q index; received from the QM is inserted to event ID. */ +#define XCM_REG_XCM_XQM_USE_Q 0x200f0 +/* [RW 4] The value by which CFC updates the activity counter at QM bypass. */ +#define XCM_REG_XQM_BYP_ACT_UPD 0x200fc +/* [RW 6] QM output initial credit. Max credit available - 32.Write writes + the initial credit value; read returns the current value of the credit + counter. Must be initialized to 32 at start-up. */ +#define XCM_REG_XQM_INIT_CRD 0x20420 +/* [RW 3] The weight of the QM (primary) input in the WRR mechanism. 0 + stands for weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_XQM_P_WEIGHT 0x200e4 +/* [RW 28] The CM header value for QM request (primary). */ +#define XCM_REG_XQM_XCM_HDR_P 0x200a0 +/* [RW 28] The CM header value for QM request (secondary). */ +#define XCM_REG_XQM_XCM_HDR_S 0x200a4 +/* [RW 1] QM - CM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XQM_XCM_IFEN 0x20014 +/* [RW 1] Input SDM Interface enable. If 0 - the valid input is disregarded; + acknowledge output is deasserted; all other signals are treated as usual; + if 1 - normal activity. */ +#define XCM_REG_XSDM_IFEN 0x20018 +/* [RC 1] Set at message length mismatch (relative to last indication) at + the SDM interface. */ +#define XCM_REG_XSDM_LENGTH_MIS 0x20220 +/* [RW 3] The weight of the SDM input in the WRR mechanism. 0 stands for + weight 8 (the most prioritised); 1 stands for weight 1(least + prioritised); 2 stands for weight 2; tc. */ +#define XCM_REG_XSDM_WEIGHT 0x200e0 +/* [RW 17] Indirect access to the descriptor table of the XX protection + mechanism. The fields are: [5:0] - message length; 11:6] - message + pointer; 16:12] - next pointer. */ +#define XCM_REG_XX_DESCR_TABLE 0x20480 +/* [R 6] Used to read the XX protection Free counter. */ +#define XCM_REG_XX_FREE 0x20240 +/* [RW 6] Initial value for the credit counter; responsible for fulfilling + of the Input Stage XX protection buffer by the XX protection pending + messages. Max credit available - 3.Write writes the initial credit value; + read returns the current value of the credit counter. Must be initialized + to 2 at start-up. */ +#define XCM_REG_XX_INIT_CRD 0x20424 +/* [RW 6] The maximum number of pending messages; which may be stored in XX + protection. ~xcm_registers_xx_free.xx_free read on read. */ +#define XCM_REG_XX_MSG_NUM 0x20428 +/* [RW 8] The Event ID; sent to the STORM in case of XX overflow. */ +#define XCM_REG_XX_OVFL_EVNT_ID 0x20058 +/* [RW 15] Indirect access to the XX table of the XX protection mechanism. + The fields are:[4:0] - tail pointer; 9:5] - Link List size; 14:10] - + header pointer. */ +#define XCM_REG_XX_TABLE 0x20500 +/* [RW 8] The event id for aggregated interrupt 0 */ +#define XSDM_REG_AGG_INT_EVENT_0 0x166038 +#define XSDM_REG_AGG_INT_EVENT_1 0x16603c +#define XSDM_REG_AGG_INT_EVENT_10 0x166060 +#define XSDM_REG_AGG_INT_EVENT_11 0x166064 +#define XSDM_REG_AGG_INT_EVENT_12 0x166068 +#define XSDM_REG_AGG_INT_EVENT_13 0x16606c +#define XSDM_REG_AGG_INT_EVENT_14 0x166070 +#define XSDM_REG_AGG_INT_EVENT_15 0x166074 +#define XSDM_REG_AGG_INT_EVENT_16 0x166078 +#define XSDM_REG_AGG_INT_EVENT_17 0x16607c +#define XSDM_REG_AGG_INT_EVENT_18 0x166080 +#define XSDM_REG_AGG_INT_EVENT_19 0x166084 +#define XSDM_REG_AGG_INT_EVENT_2 0x166040 +#define XSDM_REG_AGG_INT_EVENT_20 0x166088 +#define XSDM_REG_AGG_INT_EVENT_21 0x16608c +#define XSDM_REG_AGG_INT_EVENT_22 0x166090 +#define XSDM_REG_AGG_INT_EVENT_23 0x166094 +#define XSDM_REG_AGG_INT_EVENT_24 0x166098 +#define XSDM_REG_AGG_INT_EVENT_25 0x16609c +#define XSDM_REG_AGG_INT_EVENT_26 0x1660a0 +#define XSDM_REG_AGG_INT_EVENT_27 0x1660a4 +#define XSDM_REG_AGG_INT_EVENT_28 0x1660a8 +#define XSDM_REG_AGG_INT_EVENT_29 0x1660ac +/* [RW 1] For each aggregated interrupt index whether the mode is normal (0) + or auto-mask-mode (1) */ +#define XSDM_REG_AGG_INT_MODE_0 0x1661b8 +#define XSDM_REG_AGG_INT_MODE_1 0x1661bc +#define XSDM_REG_AGG_INT_MODE_10 0x1661e0 +#define XSDM_REG_AGG_INT_MODE_11 0x1661e4 +#define XSDM_REG_AGG_INT_MODE_12 0x1661e8 +#define XSDM_REG_AGG_INT_MODE_13 0x1661ec +#define XSDM_REG_AGG_INT_MODE_14 0x1661f0 +#define XSDM_REG_AGG_INT_MODE_15 0x1661f4 +#define XSDM_REG_AGG_INT_MODE_16 0x1661f8 +#define XSDM_REG_AGG_INT_MODE_17 0x1661fc +#define XSDM_REG_AGG_INT_MODE_18 0x166200 +#define XSDM_REG_AGG_INT_MODE_19 0x166204 +/* [RW 13] The start address in the internal RAM for the cfc_rsp lcid */ +#define XSDM_REG_CFC_RSP_START_ADDR 0x166008 +/* [RW 16] The maximum value of the competion counter #0 */ +#define XSDM_REG_CMP_COUNTER_MAX0 0x16601c +/* [RW 16] The maximum value of the competion counter #1 */ +#define XSDM_REG_CMP_COUNTER_MAX1 0x166020 +/* [RW 16] The maximum value of the competion counter #2 */ +#define XSDM_REG_CMP_COUNTER_MAX2 0x166024 +/* [RW 16] The maximum value of the competion counter #3 */ +#define XSDM_REG_CMP_COUNTER_MAX3 0x166028 +/* [RW 13] The start address in the internal RAM for the completion + counters. */ +#define XSDM_REG_CMP_COUNTER_START_ADDR 0x16600c +#define XSDM_REG_ENABLE_IN1 0x166238 +#define XSDM_REG_ENABLE_IN2 0x16623c +#define XSDM_REG_ENABLE_OUT1 0x166240 +#define XSDM_REG_ENABLE_OUT2 0x166244 +/* [RW 4] The initial number of messages that can be sent to the pxp control + interface without receiving any ACK. */ +#define XSDM_REG_INIT_CREDIT_PXP_CTRL 0x1664bc +/* [ST 32] The number of ACK after placement messages received */ +#define XSDM_REG_NUM_OF_ACK_AFTER_PLACE 0x16627c +/* [ST 32] The number of packet end messages received from the parser */ +#define XSDM_REG_NUM_OF_PKT_END_MSG 0x166274 +/* [ST 32] The number of requests received from the pxp async if */ +#define XSDM_REG_NUM_OF_PXP_ASYNC_REQ 0x166278 +/* [ST 32] The number of commands received in queue 0 */ +#define XSDM_REG_NUM_OF_Q0_CMD 0x166248 +/* [ST 32] The number of commands received in queue 10 */ +#define XSDM_REG_NUM_OF_Q10_CMD 0x16626c +/* [ST 32] The number of commands received in queue 11 */ +#define XSDM_REG_NUM_OF_Q11_CMD 0x166270 +/* [ST 32] The number of commands received in queue 1 */ +#define XSDM_REG_NUM_OF_Q1_CMD 0x16624c +/* [ST 32] The number of commands received in queue 3 */ +#define XSDM_REG_NUM_OF_Q3_CMD 0x166250 +/* [ST 32] The number of commands received in queue 4 */ +#define XSDM_REG_NUM_OF_Q4_CMD 0x166254 +/* [ST 32] The number of commands received in queue 5 */ +#define XSDM_REG_NUM_OF_Q5_CMD 0x166258 +/* [ST 32] The number of commands received in queue 6 */ +#define XSDM_REG_NUM_OF_Q6_CMD 0x16625c +/* [ST 32] The number of commands received in queue 7 */ +#define XSDM_REG_NUM_OF_Q7_CMD 0x166260 +/* [ST 32] The number of commands received in queue 8 */ +#define XSDM_REG_NUM_OF_Q8_CMD 0x166264 +/* [ST 32] The number of commands received in queue 9 */ +#define XSDM_REG_NUM_OF_Q9_CMD 0x166268 +/* [RW 13] The start address in the internal RAM for queue counters */ +#define XSDM_REG_Q_COUNTER_START_ADDR 0x166010 +/* [R 1] pxp_ctrl rd_data fifo empty in sdm_dma_rsp block */ +#define XSDM_REG_RSP_PXP_CTRL_RDATA_EMPTY 0x166548 +/* [R 1] parser fifo empty in sdm_sync block */ +#define XSDM_REG_SYNC_PARSER_EMPTY 0x166550 +/* [R 1] parser serial fifo empty in sdm_sync block */ +#define XSDM_REG_SYNC_SYNC_EMPTY 0x166558 +/* [RW 32] Tick for timer counter. Applicable only when + ~xsdm_registers_timer_tick_enable.timer_tick_enable =1 */ +#define XSDM_REG_TIMER_TICK 0x166000 +/* [RW 32] Interrupt mask register #0 read/write */ +#define XSDM_REG_XSDM_INT_MASK_0 0x16629c +#define XSDM_REG_XSDM_INT_MASK_1 0x1662ac +/* [RW 11] Parity mask register #0 read/write */ +#define XSDM_REG_XSDM_PRTY_MASK 0x1662bc +/* [RW 5] The number of time_slots in the arbitration cycle */ +#define XSEM_REG_ARB_CYCLE_SIZE 0x280034 +/* [RW 3] The source that is associated with arbitration element 0. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2 */ +#define XSEM_REG_ARB_ELEMENT0 0x280020 +/* [RW 3] The source that is associated with arbitration element 1. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~xsem_registers_arb_element0.arb_element0 */ +#define XSEM_REG_ARB_ELEMENT1 0x280024 +/* [RW 3] The source that is associated with arbitration element 2. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~xsem_registers_arb_element0.arb_element0 + and ~xsem_registers_arb_element1.arb_element1 */ +#define XSEM_REG_ARB_ELEMENT2 0x280028 +/* [RW 3] The source that is associated with arbitration element 3. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2.Could + not be equal to register ~xsem_registers_arb_element0.arb_element0 and + ~xsem_registers_arb_element1.arb_element1 and + ~xsem_registers_arb_element2.arb_element2 */ +#define XSEM_REG_ARB_ELEMENT3 0x28002c +/* [RW 3] The source that is associated with arbitration element 4. Source + decoding is: 0- foc0; 1-fic1; 2-sleeping thread with priority 0; 3- + sleeping thread with priority 1; 4- sleeping thread with priority 2. + Could not be equal to register ~xsem_registers_arb_element0.arb_element0 + and ~xsem_registers_arb_element1.arb_element1 and + ~xsem_registers_arb_element2.arb_element2 and + ~xsem_registers_arb_element3.arb_element3 */ +#define XSEM_REG_ARB_ELEMENT4 0x280030 +#define XSEM_REG_ENABLE_IN 0x2800a4 +#define XSEM_REG_ENABLE_OUT 0x2800a8 +/* [RW 32] This address space contains all registers and memories that are + placed in SEM_FAST block. The SEM_FAST registers are described in + appendix B. In order to access the SEM_FAST registers the base address + XSEM_REGISTERS_FAST_MEMORY (Offset: 0x2a0000) should be added to each + SEM_FAST register offset. */ +#define XSEM_REG_FAST_MEMORY 0x2a0000 +/* [RW 1] Disables input messages from FIC0 May be updated during run_time + by the microcode */ +#define XSEM_REG_FIC0_DISABLE 0x280224 +/* [RW 1] Disables input messages from FIC1 May be updated during run_time + by the microcode */ +#define XSEM_REG_FIC1_DISABLE 0x280234 +/* [RW 15] Interrupt table Read and write access to it is not possible in + the middle of the work */ +#define XSEM_REG_INT_TABLE 0x280400 +/* [ST 24] Statistics register. The number of messages that entered through + FIC0 */ +#define XSEM_REG_MSG_NUM_FIC0 0x280000 +/* [ST 24] Statistics register. The number of messages that entered through + FIC1 */ +#define XSEM_REG_MSG_NUM_FIC1 0x280004 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC0 */ +#define XSEM_REG_MSG_NUM_FOC0 0x280008 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC1 */ +#define XSEM_REG_MSG_NUM_FOC1 0x28000c +/* [ST 24] Statistics register. The number of messages that were sent to + FOC2 */ +#define XSEM_REG_MSG_NUM_FOC2 0x280010 +/* [ST 24] Statistics register. The number of messages that were sent to + FOC3 */ +#define XSEM_REG_MSG_NUM_FOC3 0x280014 +/* [RW 1] Disables input messages from the passive buffer May be updated + during run_time by the microcode */ +#define XSEM_REG_PAS_DISABLE 0x28024c +/* [WB 128] Debug only. Passive buffer memory */ +#define XSEM_REG_PASSIVE_BUFFER 0x282000 +/* [WB 46] pram memory. B45 is parity; b[44:0] - data. */ +#define XSEM_REG_PRAM 0x2c0000 +/* [R 16] Valid sleeping threads indication have bit per thread */ +#define XSEM_REG_SLEEP_THREADS_VALID 0x28026c +/* [R 1] EXT_STORE FIFO is empty in sem_slow_ls_ext */ +#define XSEM_REG_SLOW_EXT_STORE_EMPTY 0x2802a0 +/* [RW 16] List of free threads . There is a bit per thread. */ +#define XSEM_REG_THREADS_LIST 0x2802e4 +/* [RW 3] The arbitration scheme of time_slot 0 */ +#define XSEM_REG_TS_0_AS 0x280038 +/* [RW 3] The arbitration scheme of time_slot 10 */ +#define XSEM_REG_TS_10_AS 0x280060 +/* [RW 3] The arbitration scheme of time_slot 11 */ +#define XSEM_REG_TS_11_AS 0x280064 +/* [RW 3] The arbitration scheme of time_slot 12 */ +#define XSEM_REG_TS_12_AS 0x280068 +/* [RW 3] The arbitration scheme of time_slot 13 */ +#define XSEM_REG_TS_13_AS 0x28006c +/* [RW 3] The arbitration scheme of time_slot 14 */ +#define XSEM_REG_TS_14_AS 0x280070 +/* [RW 3] The arbitration scheme of time_slot 15 */ +#define XSEM_REG_TS_15_AS 0x280074 +/* [RW 3] The arbitration scheme of time_slot 16 */ +#define XSEM_REG_TS_16_AS 0x280078 +/* [RW 3] The arbitration scheme of time_slot 17 */ +#define XSEM_REG_TS_17_AS 0x28007c +/* [RW 3] The arbitration scheme of time_slot 18 */ +#define XSEM_REG_TS_18_AS 0x280080 +/* [RW 3] The arbitration scheme of time_slot 1 */ +#define XSEM_REG_TS_1_AS 0x28003c +/* [RW 3] The arbitration scheme of time_slot 2 */ +#define XSEM_REG_TS_2_AS 0x280040 +/* [RW 3] The arbitration scheme of time_slot 3 */ +#define XSEM_REG_TS_3_AS 0x280044 +/* [RW 3] The arbitration scheme of time_slot 4 */ +#define XSEM_REG_TS_4_AS 0x280048 +/* [RW 3] The arbitration scheme of time_slot 5 */ +#define XSEM_REG_TS_5_AS 0x28004c +/* [RW 3] The arbitration scheme of time_slot 6 */ +#define XSEM_REG_TS_6_AS 0x280050 +/* [RW 3] The arbitration scheme of time_slot 7 */ +#define XSEM_REG_TS_7_AS 0x280054 +/* [RW 3] The arbitration scheme of time_slot 8 */ +#define XSEM_REG_TS_8_AS 0x280058 +/* [RW 3] The arbitration scheme of time_slot 9 */ +#define XSEM_REG_TS_9_AS 0x28005c +/* [RW 32] Interrupt mask register #0 read/write */ +#define XSEM_REG_XSEM_INT_MASK_0 0x280110 +#define XSEM_REG_XSEM_INT_MASK_1 0x280120 +/* [RW 32] Parity mask register #0 read/write */ +#define XSEM_REG_XSEM_PRTY_MASK_0 0x280130 +#define XSEM_REG_XSEM_PRTY_MASK_1 0x280140 +#define MCPR_NVM_ACCESS_ENABLE_EN (1L<<0) +#define MCPR_NVM_ACCESS_ENABLE_WR_EN (1L<<1) +#define MCPR_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) +#define MCPR_NVM_CFG4_FLASH_SIZE (0x7L<<0) +#define MCPR_NVM_COMMAND_DOIT (1L<<4) +#define MCPR_NVM_COMMAND_DONE (1L<<3) +#define MCPR_NVM_COMMAND_FIRST (1L<<7) +#define MCPR_NVM_COMMAND_LAST (1L<<8) +#define MCPR_NVM_COMMAND_WR (1L<<5) +#define MCPR_NVM_COMMAND_WREN (1L<<16) +#define MCPR_NVM_COMMAND_WREN_BITSHIFT 16 +#define MCPR_NVM_COMMAND_WRDI (1L<<17) +#define MCPR_NVM_COMMAND_WRDI_BITSHIFT 17 +#define MCPR_NVM_SW_ARB_ARB_ARB1 (1L<<9) +#define MCPR_NVM_SW_ARB_ARB_REQ_CLR1 (1L<<5) +#define MCPR_NVM_SW_ARB_ARB_REQ_SET1 (1L<<1) +#define BIGMAC_REGISTER_BMAC_CONTROL (0x00<<3) +#define BIGMAC_REGISTER_BMAC_XGXS_CONTROL (0x01<<3) +#define BIGMAC_REGISTER_CNT_MAX_SIZE (0x05<<3) +#define BIGMAC_REGISTER_RX_CONTROL (0x21<<3) +#define BIGMAC_REGISTER_RX_LLFC_MSG_FLDS (0x46<<3) +#define BIGMAC_REGISTER_RX_MAX_SIZE (0x23<<3) +#define BIGMAC_REGISTER_RX_STAT_GR64 (0x26<<3) +#define BIGMAC_REGISTER_RX_STAT_GRIPJ (0x42<<3) +#define BIGMAC_REGISTER_TX_CONTROL (0x07<<3) +#define BIGMAC_REGISTER_TX_MAX_SIZE (0x09<<3) +#define BIGMAC_REGISTER_TX_PAUSE_THRESHOLD (0x0A<<3) +#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 EMAC_MDIO_COMM_COMMAND_ADDRESS (0L<<26) +#define EMAC_MDIO_COMM_COMMAND_READ_22 (2L<<26) +#define EMAC_MDIO_COMM_COMMAND_READ_45 (3L<<26) +#define EMAC_MDIO_COMM_COMMAND_WRITE_22 (1L<<26) +#define EMAC_MDIO_COMM_COMMAND_WRITE_45 (1L<<26) +#define EMAC_MDIO_COMM_DATA (0xffffL<<0) +#define EMAC_MDIO_COMM_START_BUSY (1L<<29) +#define EMAC_MDIO_MODE_AUTO_POLL (1L<<4) +#define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31) +#define EMAC_MODE_25G_MODE (1L<<5) +#define EMAC_MODE_ACPI_RCVD (1L<<20) +#define EMAC_MODE_HALF_DUPLEX (1L<<1) +#define EMAC_MODE_MPKT (1L<<18) +#define EMAC_MODE_MPKT_RCVD (1L<<19) +#define EMAC_MODE_PORT_GMII (2L<<2) +#define EMAC_MODE_PORT_MII (1L<<2) +#define EMAC_MODE_PORT_MII_10M (3L<<2) +#define EMAC_MODE_RESET (1L<<0) +#define EMAC_REG_EMAC_MAC_MATCH 0x10 +#define EMAC_REG_EMAC_MDIO_COMM 0xac +#define EMAC_REG_EMAC_MDIO_MODE 0xb4 +#define EMAC_REG_EMAC_MODE 0x0 +#define EMAC_REG_EMAC_RX_MODE 0xc8 +#define EMAC_REG_EMAC_RX_MTU_SIZE 0x9c +#define EMAC_REG_EMAC_RX_STAT_AC 0x180 +#define EMAC_REG_EMAC_RX_STAT_AC_28 0x1f4 +#define EMAC_REG_EMAC_RX_STAT_AC_COUNT 23 +#define EMAC_REG_EMAC_TX_MODE 0xbc +#define EMAC_REG_EMAC_TX_STAT_AC 0x280 +#define EMAC_REG_EMAC_TX_STAT_AC_COUNT 22 +#define EMAC_RX_MODE_FLOW_EN (1L<<2) +#define EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) +#define EMAC_RX_MODE_PROMISCUOUS (1L<<8) +#define EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) +#define EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) +#define EMAC_TX_MODE_RESET (1L<<0) +#define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 +#define MISC_REGISTERS_RESET_REG_1_SET 0x584 +#define MISC_REGISTERS_RESET_REG_2_CLEAR 0x598 +#define MISC_REGISTERS_RESET_REG_2_RST_BMAC0 (0x1<<0) +#define MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE (0x1<<14) +#define MISC_REGISTERS_RESET_REG_2_SET 0x594 +#define MISC_REGISTERS_RESET_REG_3_CLEAR 0x5a8 +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ (0x1<<1) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN (0x1<<2) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD (0x1<<3) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW (0x1<<0) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ (0x1<<5) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN (0x1<<6) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD (0x1<<7) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW (0x1<<4) +#define MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB (0x1<<8) +#define MISC_REGISTERS_RESET_REG_3_SET 0x5a4 +#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) +#define AEU_INPUTS_ATTN_BITS_CDU_PARITY_ERROR (1<<8) +#define AEU_INPUTS_ATTN_BITS_CFC_HW_INTERRUPT (1<<7) +#define AEU_INPUTS_ATTN_BITS_CFC_PARITY_ERROR (1<<6) +#define AEU_INPUTS_ATTN_BITS_CSDM_HW_INTERRUPT (1<<29) +#define AEU_INPUTS_ATTN_BITS_CSDM_PARITY_ERROR (1<<28) +#define AEU_INPUTS_ATTN_BITS_CSEMI_HW_INTERRUPT (1<<1) +#define AEU_INPUTS_ATTN_BITS_CSEMI_PARITY_ERROR (1<<0) +#define AEU_INPUTS_ATTN_BITS_DEBUG_PARITY_ERROR (1<<18) +#define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) +#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) +#define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) +#define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) +#define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15) +#define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14) +#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_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) +#define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR (1<<4) +#define AEU_INPUTS_ATTN_BITS_QM_HW_INTERRUPT (1<<3) +#define AEU_INPUTS_ATTN_BITS_QM_PARITY_ERROR (1<<2) +#define AEU_INPUTS_ATTN_BITS_SEARCHER_PARITY_ERROR (1<<22) +#define AEU_INPUTS_ATTN_BITS_TCM_HW_INTERRUPT (1<<27) +#define AEU_INPUTS_ATTN_BITS_TIMERS_HW_INTERRUPT (1<<5) +#define AEU_INPUTS_ATTN_BITS_TSDM_HW_INTERRUPT (1<<25) +#define AEU_INPUTS_ATTN_BITS_TSDM_PARITY_ERROR (1<<24) +#define AEU_INPUTS_ATTN_BITS_TSEMI_HW_INTERRUPT (1<<29) +#define AEU_INPUTS_ATTN_BITS_TSEMI_PARITY_ERROR (1<<28) +#define AEU_INPUTS_ATTN_BITS_UCM_HW_INTERRUPT (1<<23) +#define AEU_INPUTS_ATTN_BITS_UPB_HW_INTERRUPT (1<<27) +#define AEU_INPUTS_ATTN_BITS_UPB_PARITY_ERROR (1<<26) +#define AEU_INPUTS_ATTN_BITS_USDM_HW_INTERRUPT (1<<21) +#define AEU_INPUTS_ATTN_BITS_USDM_PARITY_ERROR (1<<20) +#define AEU_INPUTS_ATTN_BITS_USEMI_HW_INTERRUPT (1<<25) +#define AEU_INPUTS_ATTN_BITS_USEMI_PARITY_ERROR (1<<24) +#define AEU_INPUTS_ATTN_BITS_VAUX_PCI_CORE_PARITY_ERROR (1<<16) +#define AEU_INPUTS_ATTN_BITS_XCM_HW_INTERRUPT (1<<9) +#define AEU_INPUTS_ATTN_BITS_XSDM_HW_INTERRUPT (1<<7) +#define AEU_INPUTS_ATTN_BITS_XSDM_PARITY_ERROR (1<<6) +#define AEU_INPUTS_ATTN_BITS_XSEMI_HW_INTERRUPT (1<<11) +#define AEU_INPUTS_ATTN_BITS_XSEMI_PARITY_ERROR (1<<10) +#define RESERVED_GENERAL_ATTENTION_BIT_0 0 + +#define EVEREST_GEN_ATTN_IN_USE_MASK 0x3e0 +#define EVEREST_LATCHED_ATTN_IN_USE_MASK 0xffe00000 + +#define RESERVED_GENERAL_ATTENTION_BIT_6 6 +#define RESERVED_GENERAL_ATTENTION_BIT_7 7 +#define RESERVED_GENERAL_ATTENTION_BIT_8 8 +#define RESERVED_GENERAL_ATTENTION_BIT_9 9 +#define RESERVED_GENERAL_ATTENTION_BIT_10 10 +#define RESERVED_GENERAL_ATTENTION_BIT_11 11 +#define RESERVED_GENERAL_ATTENTION_BIT_12 12 +#define RESERVED_GENERAL_ATTENTION_BIT_13 13 +#define RESERVED_GENERAL_ATTENTION_BIT_14 14 +#define RESERVED_GENERAL_ATTENTION_BIT_15 15 +#define RESERVED_GENERAL_ATTENTION_BIT_16 16 +#define RESERVED_GENERAL_ATTENTION_BIT_17 17 +#define RESERVED_GENERAL_ATTENTION_BIT_18 18 +#define RESERVED_GENERAL_ATTENTION_BIT_19 19 +#define RESERVED_GENERAL_ATTENTION_BIT_20 20 +#define RESERVED_GENERAL_ATTENTION_BIT_21 21 + +/* storm asserts attention bits */ +#define TSTORM_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_7 +#define USTORM_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_8 +#define CSTORM_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_9 +#define XSTORM_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_10 + +/* mcp error attention bit */ +#define MCP_FATAL_ASSERT_ATTENTION_BIT RESERVED_GENERAL_ATTENTION_BIT_11 + +#define LATCHED_ATTN_RBCR 23 +#define LATCHED_ATTN_RBCT 24 +#define LATCHED_ATTN_RBCN 25 +#define LATCHED_ATTN_RBCU 26 +#define LATCHED_ATTN_RBCP 27 +#define LATCHED_ATTN_TIMEOUT_GRC 28 +#define LATCHED_ATTN_RSVD_GRC 29 +#define LATCHED_ATTN_ROM_PARITY_MCP 30 +#define LATCHED_ATTN_UM_RX_PARITY_MCP 31 +#define LATCHED_ATTN_UM_TX_PARITY_MCP 32 +#define LATCHED_ATTN_SCPAD_PARITY_MCP 33 + +#define GENERAL_ATTEN_WORD(atten_name) ((94 + atten_name) / 32) +#define GENERAL_ATTEN_OFFSET(atten_name) (1 << ((94 + atten_name) % 32)) +/* + * This file defines GRC base address for every block. + * This file is included by chipsim, asm microcode and cpp microcode. + * These values are used in Design.xml on regBase attribute + * Use the base with the generated offsets of specific registers. + */ + +#define GRCBASE_PXPCS 0x000000 +#define GRCBASE_PCICONFIG 0x002000 +#define GRCBASE_PCIREG 0x002400 +#define GRCBASE_EMAC0 0x008000 +#define GRCBASE_EMAC1 0x008400 +#define GRCBASE_DBU 0x008800 +#define GRCBASE_MISC 0x00A000 +#define GRCBASE_DBG 0x00C000 +#define GRCBASE_NIG 0x010000 +#define GRCBASE_XCM 0x020000 +#define GRCBASE_PRS 0x040000 +#define GRCBASE_SRCH 0x040400 +#define GRCBASE_TSDM 0x042000 +#define GRCBASE_TCM 0x050000 +#define GRCBASE_BRB1 0x060000 +#define GRCBASE_MCP 0x080000 +#define GRCBASE_UPB 0x0C1000 +#define GRCBASE_CSDM 0x0C2000 +#define GRCBASE_USDM 0x0C4000 +#define GRCBASE_CCM 0x0D0000 +#define GRCBASE_UCM 0x0E0000 +#define GRCBASE_CDU 0x101000 +#define GRCBASE_DMAE 0x102000 +#define GRCBASE_PXP 0x103000 +#define GRCBASE_CFC 0x104000 +#define GRCBASE_HC 0x108000 +#define GRCBASE_PXP2 0x120000 +#define GRCBASE_PBF 0x140000 +#define GRCBASE_XPB 0x161000 +#define GRCBASE_TIMERS 0x164000 +#define GRCBASE_XSDM 0x166000 +#define GRCBASE_QM 0x168000 +#define GRCBASE_DQ 0x170000 +#define GRCBASE_TSEM 0x180000 +#define GRCBASE_CSEM 0x200000 +#define GRCBASE_XSEM 0x280000 +#define GRCBASE_USEM 0x300000 +#define GRCBASE_MISC_AEU GRCBASE_MISC + + +/*the offset of the configuration space in the pci core register*/ +#define PCICFG_OFFSET 0x2000 +#define PCICFG_VENDOR_ID_OFFSET 0x00 +#define PCICFG_DEVICE_ID_OFFSET 0x02 +#define PCICFG_SUBSYSTEM_VENDOR_ID_OFFSET 0x2c +#define PCICFG_SUBSYSTEM_ID_OFFSET 0x2e +#define PCICFG_INT_LINE 0x3c +#define PCICFG_INT_PIN 0x3d +#define PCICFG_CACHE_LINE_SIZE 0x0c +#define PCICFG_LATENCY_TIMER 0x0d +#define PCICFG_REVESION_ID 0x08 +#define PCICFG_BAR_1_LOW 0x10 +#define PCICFG_BAR_1_HIGH 0x14 +#define PCICFG_BAR_2_LOW 0x18 +#define PCICFG_BAR_2_HIGH 0x1c +#define PCICFG_GRC_ADDRESS 0x78 +#define PCICFG_GRC_DATA 0x80 +#define PCICFG_DEVICE_CONTROL 0xb4 +#define PCICFG_LINK_CONTROL 0xbc + +#define BAR_USTRORM_INTMEM 0x400000 +#define BAR_CSTRORM_INTMEM 0x410000 +#define BAR_XSTRORM_INTMEM 0x420000 +#define BAR_TSTRORM_INTMEM 0x430000 + +#define BAR_IGU_INTMEM 0x440000 + +#define BAR_DOORBELL_OFFSET 0x800000 + +#define BAR_ME_REGISTER 0x450000 + + +#define GRC_CONFIG_2_SIZE_REG 0x408 /* config_2 offset */ +#define PCI_CONFIG_2_BAR1_SIZE (0xfL<<0) +#define PCI_CONFIG_2_BAR1_SIZE_DISABLED (0L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_64K (1L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_128K (2L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_256K (3L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_512K (4L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_1M (5L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_2M (6L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_4M (7L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_8M (8L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_16M (9L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_32M (10L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_64M (11L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_128M (12L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_256M (13L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_512M (14L<<0) +#define PCI_CONFIG_2_BAR1_SIZE_1G (15L<<0) +#define PCI_CONFIG_2_BAR1_64ENA (1L<<4) +#define PCI_CONFIG_2_EXP_ROM_RETRY (1L<<5) +#define PCI_CONFIG_2_CFG_CYCLE_RETRY (1L<<6) +#define PCI_CONFIG_2_FIRST_CFG_DONE (1L<<7) +#define PCI_CONFIG_2_EXP_ROM_SIZE (0xffL<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED (0L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_2K (1L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_4K (2L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_8K (3L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_16K (4L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_32K (5L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_64K (6L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_128K (7L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_256K (8L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_512K (9L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_1M (10L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_2M (11L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_4M (12L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_8M (13L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_16M (14L<<8) +#define PCI_CONFIG_2_EXP_ROM_SIZE_32M (15L<<8) +#define PCI_CONFIG_2_BAR_PREFETCH (1L<<16) +#define PCI_CONFIG_2_RESERVED0 (0x7fffL<<17) + +/* config_3 offset */ +#define GRC_CONFIG_3_SIZE_REG (0x40c) +#define PCI_CONFIG_3_STICKY_BYTE (0xffL<<0) +#define PCI_CONFIG_3_FORCE_PME (1L<<24) +#define PCI_CONFIG_3_PME_STATUS (1L<<25) +#define PCI_CONFIG_3_PME_ENABLE (1L<<26) +#define PCI_CONFIG_3_PM_STATE (0x3L<<27) +#define PCI_CONFIG_3_VAUX_PRESET (1L<<30) +#define PCI_CONFIG_3_PCI_POWER (1L<<31) + +/* config_2 offset */ +#define GRC_CONFIG_2_SIZE_REG 0x408 + +#define GRC_BAR2_CONFIG 0x4e0 +#define PCI_CONFIG_2_BAR2_SIZE (0xfL<<0) +#define PCI_CONFIG_2_BAR2_SIZE_DISABLED (0L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_64K (1L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_128K (2L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_256K (3L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_512K (4L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_1M (5L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_2M (6L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_4M (7L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_8M (8L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_16M (9L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_32M (10L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_64M (11L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_128M (12L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_256M (13L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_512M (14L<<0) +#define PCI_CONFIG_2_BAR2_SIZE_1G (15L<<0) +#define PCI_CONFIG_2_BAR2_64ENA (1L<<4) + +#define PCI_PM_DATA_A (0x410) +#define PCI_PM_DATA_B (0x414) +#define PCI_ID_VAL1 (0x434) +#define PCI_ID_VAL2 (0x438) + +#define MDIO_REG_BANK_CL73_IEEEB0 0x0 +#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL 0x0 +#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN 0x0200 +#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN 0x1000 +#define MDIO_CL73_IEEEB0_CL73_AN_CONTROL_MAIN_RST 0x8000 + +#define MDIO_REG_BANK_CL73_IEEEB1 0x10 +#define MDIO_CL73_IEEEB1_AN_ADV2 0x01 +#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M 0x0000 +#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX 0x0020 +#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 0x0040 +#define MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR 0x0080 + +#define MDIO_REG_BANK_RX0 0x80b0 +#define MDIO_RX0_RX_EQ_BOOST 0x1c +#define MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7 +#define MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL 0x10 + +#define MDIO_REG_BANK_RX1 0x80c0 +#define MDIO_RX1_RX_EQ_BOOST 0x1c +#define MDIO_RX1_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7 +#define MDIO_RX1_RX_EQ_BOOST_OFFSET_CTRL 0x10 + +#define MDIO_REG_BANK_RX2 0x80d0 +#define MDIO_RX2_RX_EQ_BOOST 0x1c +#define MDIO_RX2_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7 +#define MDIO_RX2_RX_EQ_BOOST_OFFSET_CTRL 0x10 + +#define MDIO_REG_BANK_RX3 0x80e0 +#define MDIO_RX3_RX_EQ_BOOST 0x1c +#define MDIO_RX3_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7 +#define MDIO_RX3_RX_EQ_BOOST_OFFSET_CTRL 0x10 + +#define MDIO_REG_BANK_RX_ALL 0x80f0 +#define MDIO_RX_ALL_RX_EQ_BOOST 0x1c +#define MDIO_RX_ALL_RX_EQ_BOOST_EQUALIZER_CTRL_MASK 0x7 +#define MDIO_RX_ALL_RX_EQ_BOOST_OFFSET_CTRL 0x10 + +#define MDIO_REG_BANK_TX0 0x8060 +#define MDIO_TX0_TX_DRIVER 0x17 +#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK 0xf000 +#define MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT 12 +#define MDIO_TX0_TX_DRIVER_IDRIVER_MASK 0x0f00 +#define MDIO_TX0_TX_DRIVER_IDRIVER_SHIFT 8 +#define MDIO_TX0_TX_DRIVER_IPREDRIVER_MASK 0x00f0 +#define MDIO_TX0_TX_DRIVER_IPREDRIVER_SHIFT 4 +#define MDIO_TX0_TX_DRIVER_IFULLSPD_MASK 0x000e +#define MDIO_TX0_TX_DRIVER_IFULLSPD_SHIFT 1 +#define MDIO_TX0_TX_DRIVER_ICBUF1T 1 + +#define MDIO_REG_BANK_XGXS_BLOCK0 0x8000 +#define MDIO_BLOCK0_XGXS_CONTROL 0x10 + +#define MDIO_REG_BANK_XGXS_BLOCK1 0x8010 +#define MDIO_BLOCK1_LANE_CTRL0 0x15 +#define MDIO_BLOCK1_LANE_CTRL1 0x16 +#define MDIO_BLOCK1_LANE_CTRL2 0x17 +#define MDIO_BLOCK1_LANE_PRBS 0x19 + +#define MDIO_REG_BANK_XGXS_BLOCK2 0x8100 +#define MDIO_XGXS_BLOCK2_RX_LN_SWAP 0x10 +#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE 0x8000 +#define MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE 0x4000 +#define MDIO_XGXS_BLOCK2_TX_LN_SWAP 0x11 +#define MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE 0x8000 +#define MDIO_XGXS_BLOCK2_TEST_MODE_LANE 0x15 + +#define MDIO_REG_BANK_GP_STATUS 0x8120 +#define MDIO_GP_STATUS_TOP_AN_STATUS1 0x1B +#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE 0x0001 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE 0x0002 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS 0x0004 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS 0x0008 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE 0x0010 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_LP_NP_BAM_ABLE 0x0020 + +#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE 0x0040 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE 0x0080 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK 0x3f00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M 0x0000 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M 0x0100 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G 0x0200 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G 0x0300 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G 0x0400 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G 0x0500 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG 0x0600 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4 0x0700 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG 0x0800 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G 0x0900 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G 0x0A00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G 0x0B00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G 0x0C00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX 0x0D00 +#define MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 0x0E00 + + +#define MDIO_REG_BANK_10G_PARALLEL_DETECT 0x8130 +#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL 0x11 +#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN 0x1 +#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK 0x13 +#define MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT (0xb71<<1) + +#define MDIO_REG_BANK_SERDES_DIGITAL 0x8300 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1 0x10 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE 0x0001 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_TBI_IF 0x0002 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN 0x0004 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT 0x0008 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET 0x0010 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE 0x0020 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2 0x11 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN 0x0001 +#define MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_AN_FST_TMR 0x0040 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1 0x14 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_DUPLEX 0x0004 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_MASK 0x0018 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_SHIFT 3 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_2_5G 0x0018 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_1G 0x0010 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_100M 0x0008 +#define MDIO_SERDES_DIGITAL_A_1000X_STATUS1_SPEED_10M 0x0000 +#define MDIO_SERDES_DIGITAL_MISC1 0x18 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_MASK 0xE000 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_25M 0x0000 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_100M 0x2000 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_125M 0x4000 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M 0x6000 +#define MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_187_5M 0x8000 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL 0x0010 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK 0x000f +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_2_5G 0x0000 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_5G 0x0001 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_6G 0x0002 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_HIG 0x0003 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4 0x0004 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12G 0x0005 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_12_5G 0x0006 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G 0x0007 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_15G 0x0008 +#define MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_16G 0x0009 + +#define MDIO_REG_BANK_OVER_1G 0x8320 +#define MDIO_OVER_1G_DIGCTL_3_4 0x14 +#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_MASK 0xffe0 +#define MDIO_OVER_1G_DIGCTL_3_4_MP_ID_SHIFT 5 +#define MDIO_OVER_1G_UP1 0x19 +#define MDIO_OVER_1G_UP1_2_5G 0x0001 +#define MDIO_OVER_1G_UP1_5G 0x0002 +#define MDIO_OVER_1G_UP1_6G 0x0004 +#define MDIO_OVER_1G_UP1_10G 0x0010 +#define MDIO_OVER_1G_UP1_10GH 0x0008 +#define MDIO_OVER_1G_UP1_12G 0x0020 +#define MDIO_OVER_1G_UP1_12_5G 0x0040 +#define MDIO_OVER_1G_UP1_13G 0x0080 +#define MDIO_OVER_1G_UP1_15G 0x0100 +#define MDIO_OVER_1G_UP1_16G 0x0200 +#define MDIO_OVER_1G_UP2 0x1A +#define MDIO_OVER_1G_UP2_IPREDRIVER_MASK 0x0007 +#define MDIO_OVER_1G_UP2_IDRIVER_MASK 0x0038 +#define MDIO_OVER_1G_UP2_PREEMPHASIS_MASK 0x03C0 +#define MDIO_OVER_1G_UP3 0x1B +#define MDIO_OVER_1G_UP3_HIGIG2 0x0001 +#define MDIO_OVER_1G_LP_UP1 0x1C +#define MDIO_OVER_1G_LP_UP2 0x1D +#define MDIO_OVER_1G_LP_UP2_MR_ADV_OVER_1G_MASK 0x03ff +#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK 0x0780 +#define MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT 7 +#define MDIO_OVER_1G_LP_UP3 0x1E + +#define MDIO_REG_BANK_BAM_NEXT_PAGE 0x8350 +#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL 0x10 +#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE 0x0001 +#define MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN 0x0002 + +#define MDIO_REG_BANK_CL73_USERB0 0x8370 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL1 0x12 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN 0x8000 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN 0x4000 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN 0x2000 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL3 0x14 +#define MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR 0x0001 + +#define MDIO_REG_BANK_AER_BLOCK 0xFFD0 +#define MDIO_AER_BLOCK_AER_REG 0x1E + +#define MDIO_REG_BANK_COMBO_IEEE0 0xFFE0 +#define MDIO_COMBO_IEEE0_MII_CONTROL 0x10 +#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK 0x2040 +#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_10 0x0000 +#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100 0x2000 +#define MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000 0x0040 +#define MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX 0x0100 +#define MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN 0x0200 +#define MDIO_COMBO_IEEO_MII_CONTROL_AN_EN 0x1000 +#define MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK 0x4000 +#define MDIO_COMBO_IEEO_MII_CONTROL_RESET 0x8000 +#define MDIO_COMBO_IEEE0_MII_STATUS 0x11 +#define MDIO_COMBO_IEEE0_MII_STATUS_LINK_PASS 0x0004 +#define MDIO_COMBO_IEEE0_MII_STATUS_AUTONEG_COMPLETE 0x0020 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV 0x14 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX 0x0020 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_HALF_DUPLEX 0x0040 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK 0x0180 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE 0x0000 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC 0x0080 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC 0x0100 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH 0x0180 +#define MDIO_COMBO_IEEE0_AUTO_NEG_ADV_NEXT_PAGE 0x8000 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1 0x15 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_NEXT_PAGE 0x8000 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_ACK 0x4000 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_MASK 0x0180 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_NONE\ + 0x0000 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_PAUSE_BOTH\ + 0x0180 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_HALF_DUP_CAP 0x0040 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_FULL_DUP_CAP 0x0020 +#define MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1_SGMII_MODE 0x0001 + + +#define EXT_PHY_OPT_PMA_PMD_DEVAD 0x1 +#define EXT_PHY_OPT_WIS_DEVAD 0x2 +#define EXT_PHY_OPT_PCS_DEVAD 0x3 +#define EXT_PHY_OPT_PHY_XS_DEVAD 0x4 +#define EXT_PHY_OPT_CNTL 0x0 +#define EXT_PHY_OPT_PMD_RX_SD 0xa +#define EXT_PHY_OPT_PMD_MISC_CNTL 0xca0a +#define EXT_PHY_OPT_PHY_IDENTIFIER 0xc800 +#define EXT_PHY_OPT_PMD_DIGITAL_CNT 0xc808 +#define EXT_PHY_OPT_PMD_DIGITAL_SATUS 0xc809 +#define EXT_PHY_OPT_CMU_PLL_BYPASS 0xca09 +#define EXT_PHY_OPT_LASI_CNTL 0x9002 +#define EXT_PHY_OPT_RX_ALARM 0x9003 +#define EXT_PHY_OPT_LASI_STATUS 0x9005 +#define EXT_PHY_OPT_PCS_STATUS 0x0020 +#define EXT_PHY_OPT_XGXS_LANE_STATUS 0x0018 + +#define EXT_PHY_KR_PMA_PMD_DEVAD 0x1 +#define EXT_PHY_KR_PCS_DEVAD 0x3 +#define EXT_PHY_KR_AUTO_NEG_DEVAD 0x7 +#define EXT_PHY_KR_CTRL 0x0000 +#define EXT_PHY_KR_CTRL2 0x0007 +#define EXT_PHY_KR_PCS_STATUS 0x0020 +#define EXT_PHY_KR_PMD_CTRL 0x0096 +#define EXT_PHY_KR_LASI_CNTL 0x9002 +#define EXT_PHY_KR_LASI_STATUS 0x9005 +#define EXT_PHY_KR_MISC_CTRL1 0xca85 +#define EXT_PHY_KR_GEN_CTRL 0xca10 +#define EXT_PHY_KR_ROM_CODE 0xca19 + diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 7df31b5..30ecbf5 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -4419,7 +4419,7 @@ static struct { {"tx_fifo_errors"}, {"tx_packets"} }; -#define CAS_NUM_STAT_KEYS (sizeof(ethtool_cassini_statnames)/ETH_GSTRING_LEN) +#define CAS_NUM_STAT_KEYS ARRAY_SIZE(ethtool_cassini_statnames) static struct { const int offsets; /* neg. values for 2nd arg to cas_read_phy */ diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index c597504..16f1313 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -1042,7 +1042,7 @@ static int __devinit init_one(struct pci_dev *pdev, pci_using_dac = 1; if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { - CH_ERR("%s: unable to obtain 64-bit DMA for" + CH_ERR("%s: unable to obtain 64-bit DMA for " "consistent allocations\n", pci_name(pdev)); err = -ENODEV; goto out_disable_pdev; diff --git a/drivers/net/chelsio/espi.c b/drivers/net/chelsio/espi.c index d7c5406..1e0749e 100644 --- a/drivers/net/chelsio/espi.c +++ b/drivers/net/chelsio/espi.c @@ -297,6 +297,7 @@ struct peespi *t1_espi_create(adapter_t *adapter) return espi; } +#if 0 void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) { struct peespi *espi = adapter->espi; @@ -309,6 +310,7 @@ void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val) writel(espi->misc_ctrl, adapter->regs + A_ESPI_MISC_CONTROL); spin_unlock(&espi->lock); } +#endif /* 0 */ u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait) { diff --git a/drivers/net/chelsio/espi.h b/drivers/net/chelsio/espi.h index 84f2c98..5694aad 100644 --- a/drivers/net/chelsio/espi.h +++ b/drivers/net/chelsio/espi.h @@ -62,7 +62,6 @@ void t1_espi_intr_disable(struct peespi *); int t1_espi_intr_handler(struct peespi *); const struct espi_intr_counts *t1_espi_get_intr_counts(struct peespi *espi); -void t1_espi_set_misc_ctrl(adapter_t *adapter, u32 val); u32 t1_espi_get_mon(adapter_t *adapter, u32 addr, u8 wait); int t1_espi_get_mon_t204(adapter_t *, u32 *, u8); diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index b301c04..8a7efd3 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -330,6 +330,8 @@ unsigned int t1_sched_update_parms(struct sge *sge, unsigned int port, return max_avail_segs * (p->mtu - 40); } +#if 0 + /* * t1_sched_max_avail_bytes() tells the scheduler the maximum amount of * data that can be pushed per port. @@ -357,6 +359,8 @@ void t1_sched_set_drain_bits_per_us(struct sge *sge, unsigned int port, t1_sched_update_parms(sge, port, 0, 0); } +#endif /* 0 */ + /* * get_clock() implements a ns clock (see ktime_get) diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h index cced9df..8c94051 100644 --- a/drivers/net/chelsio/sge.h +++ b/drivers/net/chelsio/sge.h @@ -88,8 +88,6 @@ void t1_sge_intr_disable(struct sge *); void t1_sge_intr_clear(struct sge *); const struct sge_intr_counts *t1_sge_get_intr_counts(const struct sge *sge); void t1_sge_get_port_stats(const struct sge *sge, int port, struct sge_port_stats *); -void t1_sched_set_max_avail_bytes(struct sge *, unsigned int); -void t1_sched_set_drain_bits_per_us(struct sge *, unsigned int, unsigned int); unsigned int t1_sched_update_parms(struct sge *, unsigned int, unsigned int, unsigned int); diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 6fd95a2..91d1596 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -661,9 +661,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id) int queue; u32 status; - if (!dev) - return IRQ_NONE; - priv = netdev_priv(dev); status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR); diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 61ffc92..944423c 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -76,20 +76,20 @@ enum { #define EEPROM_MAGIC 0x38E2F10C -#define CH_DEVICE(devid, ssid, idx) \ - { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, ssid, 0, 0, idx } +#define CH_DEVICE(devid, idx) \ + { PCI_VENDOR_ID_CHELSIO, devid, PCI_ANY_ID, PCI_ANY_ID, 0, 0, idx } static const struct pci_device_id cxgb3_pci_tbl[] = { - CH_DEVICE(0x20, 1, 0), /* PE9000 */ - CH_DEVICE(0x21, 1, 1), /* T302E */ - CH_DEVICE(0x22, 1, 2), /* T310E */ - CH_DEVICE(0x23, 1, 3), /* T320X */ - CH_DEVICE(0x24, 1, 1), /* T302X */ - CH_DEVICE(0x25, 1, 3), /* T320E */ - CH_DEVICE(0x26, 1, 2), /* T310X */ - CH_DEVICE(0x30, 1, 2), /* T3B10 */ - CH_DEVICE(0x31, 1, 3), /* T3B20 */ - CH_DEVICE(0x32, 1, 1), /* T3B02 */ + CH_DEVICE(0x20, 0), /* PE9000 */ + CH_DEVICE(0x21, 1), /* T302E */ + CH_DEVICE(0x22, 2), /* T310E */ + CH_DEVICE(0x23, 3), /* T320X */ + CH_DEVICE(0x24, 1), /* T302X */ + CH_DEVICE(0x25, 3), /* T320E */ + CH_DEVICE(0x26, 2), /* T310X */ + CH_DEVICE(0x30, 2), /* T3B10 */ + CH_DEVICE(0x31, 3), /* T3B20 */ + CH_DEVICE(0x32, 1), /* T3B02 */ {0,} }; @@ -336,7 +336,7 @@ static void setup_rss(struct adapter *adap) t3_config_rss(adap, F_RQFEEDBACKENABLE | F_TNLLKPEN | F_TNLMAPEN | F_TNLPRTEN | F_TNL2TUPEN | F_TNL4TUPEN | - V_RRCPLCPUSIZE(6), cpus, rspq_map); + V_RRCPLCPUSIZE(6) | F_HASHTOEPLITZ, cpus, rspq_map); } static void init_napi(struct adapter *adap) @@ -410,8 +410,7 @@ static int setup_sge_qsets(struct adapter *adap) return 0; } -static ssize_t attr_show(struct device *d, struct device_attribute *attr, - char *buf, +static ssize_t attr_show(struct device *d, char *buf, ssize_t(*format) (struct net_device *, char *)) { ssize_t len; @@ -423,7 +422,7 @@ static ssize_t attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t attr_store(struct device *d, struct device_attribute *attr, +static ssize_t attr_store(struct device *d, const char *buf, size_t len, ssize_t(*set) (struct net_device *, unsigned int), unsigned int min_val, unsigned int max_val) @@ -457,7 +456,7 @@ static ssize_t format_##name(struct net_device *dev, char *buf) \ static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ char *buf) \ { \ - return attr_show(d, attr, buf, format_##name); \ + return attr_show(d, buf, format_##name); \ } static ssize_t set_nfilters(struct net_device *dev, unsigned int val) @@ -480,7 +479,7 @@ static ssize_t set_nfilters(struct net_device *dev, unsigned int val) static ssize_t store_nfilters(struct device *d, struct device_attribute *attr, const char *buf, size_t len) { - return attr_store(d, attr, buf, len, set_nfilters, 0, ~0); + return attr_store(d, buf, len, set_nfilters, 0, ~0); } static ssize_t set_nservers(struct net_device *dev, unsigned int val) @@ -500,7 +499,7 @@ static ssize_t set_nservers(struct net_device *dev, unsigned int val) static ssize_t store_nservers(struct device *d, struct device_attribute *attr, const char *buf, size_t len) { - return attr_store(d, attr, buf, len, set_nservers, 0, ~0); + return attr_store(d, buf, len, set_nservers, 0, ~0); } #define CXGB3_ATTR_R(name, val_expr) \ @@ -524,7 +523,7 @@ static struct attribute *cxgb3_attrs[] = { static struct attribute_group cxgb3_attr_group = {.attrs = cxgb3_attrs }; -static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, +static ssize_t tm_attr_show(struct device *d, char *buf, int sched) { struct port_info *pi = netdev_priv(to_net_dev(d)); @@ -550,7 +549,7 @@ static ssize_t tm_attr_show(struct device *d, struct device_attribute *attr, return len; } -static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, +static ssize_t tm_attr_store(struct device *d, const char *buf, size_t len, int sched) { struct port_info *pi = netdev_priv(to_net_dev(d)); @@ -578,12 +577,12 @@ static ssize_t tm_attr_store(struct device *d, struct device_attribute *attr, static ssize_t show_##name(struct device *d, struct device_attribute *attr, \ char *buf) \ { \ - return tm_attr_show(d, attr, buf, sched); \ + return tm_attr_show(d, buf, sched); \ } \ static ssize_t store_##name(struct device *d, struct device_attribute *attr, \ const char *buf, size_t len) \ { \ - return tm_attr_store(d, attr, buf, len, sched); \ + return tm_attr_store(d, buf, len, sched); \ } \ static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name) @@ -720,7 +719,7 @@ static int upgrade_fw(struct adapter *adap) else dev_err(dev, "failed to upgrade to firmware %d.%d.%d\n", FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO); - + return ret; } @@ -747,7 +746,7 @@ static int update_tpsram(struct adapter *adap) struct device *dev = &adap->pdev->dev; int ret; char rev; - + rev = t3rev2char(adap); if (!rev) return 0; @@ -761,10 +760,10 @@ static int update_tpsram(struct adapter *adap) buf); return ret; } - + ret = t3_check_tpsram(adap, tpsram->data, tpsram->size); if (ret) - goto release_tpsram; + goto release_tpsram; ret = t3_set_proto_sram(adap, tpsram->data); if (ret == 0) @@ -780,7 +779,7 @@ static int update_tpsram(struct adapter *adap) release_tpsram: release_firmware(tpsram); - + return ret; } @@ -839,7 +838,8 @@ static int cxgb_up(struct adapter *adap) if (err) goto irq_err; - if (request_msix_data_irqs(adap)) { + err = request_msix_data_irqs(adap); + if (err) { free_irq(adap->msix_info[0].vec, adap); goto irq_err; } @@ -2144,7 +2144,7 @@ static void cxgb_netpoll(struct net_device *dev) for (qidx = pi->first_qset; qidx < pi->first_qset + pi->nqsets; qidx++) { struct sge_qset *qs = &adapter->sge.qs[qidx]; void *source; - + if (adapter->flags & USING_MSIX) source = qs; else @@ -2315,6 +2315,112 @@ void t3_fatal_err(struct adapter *adapter) } +/** + * t3_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci connection state + * + * This function is called after a PCI bus error affecting + * this device has been detected. + */ +static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + int i; + + /* Stop all ports */ + for_each_port(adapter, i) { + struct net_device *netdev = adapter->port[i]; + + if (netif_running(netdev)) + cxgb_close(netdev); + } + + if (is_offload(adapter) && + test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) + offload_close(&adapter->tdev); + + /* Free sge resources */ + t3_free_sge_resources(adapter); + + adapter->flags &= ~FULL_INIT_DONE; + + pci_disable_device(pdev); + + /* Request a slot slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * t3_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. + */ +static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + + if (pci_enable_device(pdev)) { + dev_err(&pdev->dev, + "Cannot re-enable PCI device after reset.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + t3_prep_adapter(adapter, adapter->params.info, 1); + + return PCI_ERS_RESULT_RECOVERED; +} + +/** + * t3_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. + */ +static void t3_io_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + int i; + + /* Restart the ports */ + for_each_port(adapter, i) { + struct net_device *netdev = adapter->port[i]; + + if (netif_running(netdev)) { + if (cxgb_open(netdev)) { + dev_err(&pdev->dev, + "can't bring device back up" + " after reset\n"); + continue; + } + netif_device_attach(netdev); + } + } + + if (is_offload(adapter)) { + __set_bit(OFFLOAD_DEVMAP_BIT, &adapter->registered_device_map); + if (offload_open(dev)) + printk(KERN_WARNING + "Could not bring back offload capabilities\n"); + } +} + +static struct pci_error_handlers t3_err_handler = { + .error_detected = t3_io_error_detected, + .slot_reset = t3_io_slot_reset, + .resume = t3_io_resume, +}; + static int __devinit cxgb_enable_msix(struct adapter *adap) { struct msix_entry entries[SGE_QSETS + 1]; @@ -2507,7 +2613,7 @@ static int __devinit init_one(struct pci_dev *pdev, err = -ENODEV; goto out_free_dev; } - + /* * The card is now ready to go. If any errors occur during device * registration we do not fail the whole card but rather proceed only @@ -2584,10 +2690,6 @@ static void __devexit remove_one(struct pci_dev *pdev) sysfs_remove_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); - for_each_port(adapter, i) - if (test_bit(i, &adapter->registered_device_map)) - unregister_netdev(adapter->port[i]); - if (is_offload(adapter)) { cxgb3_adapter_unofld(adapter); if (test_bit(OFFLOAD_DEVMAP_BIT, @@ -2595,6 +2697,10 @@ static void __devexit remove_one(struct pci_dev *pdev) offload_close(&adapter->tdev); } + for_each_port(adapter, i) + if (test_bit(i, &adapter->registered_device_map)) + unregister_netdev(adapter->port[i]); + t3_free_sge_resources(adapter); cxgb_disable_msi(adapter); @@ -2615,6 +2721,7 @@ static struct pci_driver driver = { .id_table = cxgb3_pci_tbl, .probe = init_one, .remove = __devexit_p(remove_one), + .err_handler = &t3_err_handler, }; static int __init cxgb3_init_module(void) diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index bd25421..7e5892f 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -488,7 +488,7 @@ static void t3_process_tid_release_list(struct work_struct *work) tid_release_task); struct sk_buff *skb; struct t3cdev *tdev = td->dev; - + spin_lock_bh(&td->tid_release_lock); while (td->tid_release_list) { @@ -1004,7 +1004,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) if (!is_offloading(olddev)) return; if (!is_offloading(newdev)) { - printk(KERN_WARNING "%s: Redirect to non-offload" + printk(KERN_WARNING "%s: Redirect to non-offload " "device ignored.\n", __FUNCTION__); return; } diff --git a/drivers/net/cxgb3/firmware_exports.h b/drivers/net/cxgb3/firmware_exports.h index 6a835f6..b75ddd8 100644 --- a/drivers/net/cxgb3/firmware_exports.h +++ b/drivers/net/cxgb3/firmware_exports.h @@ -76,14 +76,14 @@ #define FW_WROPCODE_MNGT 0x1D #define FW_MNGTOPCODE_PKTSCHED_SET 0x00 -/* Maximum size of a WR sent from the host, limited by the SGE. +/* Maximum size of a WR sent from the host, limited by the SGE. * - * Note: WR coming from ULP or TP are only limited by CIM. + * Note: WR coming from ULP or TP are only limited by CIM. */ #define FW_WR_SIZE 128 /* Maximum number of outstanding WRs sent from the host. Value must be - * programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by + * programmed in the CTRL/TUNNEL/QP SGE Egress Context and used by * offload modules to limit the number of WRs per connection. */ #define FW_T3_WR_NUM 16 @@ -99,7 +99,7 @@ * queues must start at SGE Egress Context FW_TUNNEL_SGEEC_START and must * start at 'TID' (or 'uP Token') FW_TUNNEL_TID_START. * - * Ingress Traffic (e.g. DMA completion credit) for TUNNEL Queue[i] is sent + * Ingress Traffic (e.g. DMA completion credit) for TUNNEL Queue[i] is sent * to RESP Queue[i]. */ #define FW_TUNNEL_NUM 8 @@ -116,10 +116,10 @@ #define FW_CTRL_SGEEC_START 65528 #define FW_CTRL_TID_START 65536 -/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These - * queues must start at SGE Egress Context FW_OFLD_SGEEC_START. - * - * Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for +/* FW_OFLD_NUM corresponds to the number of supported OFFLOAD Queues. These + * queues must start at SGE Egress Context FW_OFLD_SGEEC_START. + * + * Note: the 'uP Token' in the SGE Egress Context fields is irrelevant for * OFFLOAD Queues, as the host is responsible for providing the correct TID in * every WR. * @@ -129,14 +129,14 @@ #define FW_OFLD_SGEEC_START 0 /* - * + * */ #define FW_RI_NUM 1 #define FW_RI_SGEEC_START 65527 #define FW_RI_TID_START 65552 /* - * The RX_PKT_TID + * The RX_PKT_TID */ #define FW_RX_PKT_NUM 1 #define FW_RX_PKT_TID_START 65553 diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index 6e12bf4..70e1961 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -965,6 +965,12 @@ #define V_LOCKTID(x) ((x) << S_LOCKTID) #define F_LOCKTID V_LOCKTID(1U) +#define S_TABLELATENCYDELTA 0 +#define M_TABLELATENCYDELTA 0xf +#define V_TABLELATENCYDELTA(x) ((x) << S_TABLELATENCYDELTA) +#define G_TABLELATENCYDELTA(x) \ + (((x) >> S_TABLELATENCYDELTA) & M_TABLELATENCYDELTA) + #define A_TP_PC_CONFIG2 0x34c #define S_CHDRAFULL 4 @@ -1146,6 +1152,10 @@ #define V_RQFEEDBACKENABLE(x) ((x) << S_RQFEEDBACKENABLE) #define F_RQFEEDBACKENABLE V_RQFEEDBACKENABLE(1U) +#define S_HASHTOEPLITZ 2 +#define V_HASHTOEPLITZ(x) ((x) << S_HASHTOEPLITZ) +#define F_HASHTOEPLITZ V_HASHTOEPLITZ(1U) + #define S_DISABLE 0 #define A_TP_TM_PIO_ADDR 0x418 @@ -1198,6 +1208,14 @@ #define A_TP_INT_ENABLE 0x470 +#define S_FLMTXFLSTEMPTY 30 +#define V_FLMTXFLSTEMPTY(x) ((x) << S_FLMTXFLSTEMPTY) +#define F_FLMTXFLSTEMPTY V_FLMTXFLSTEMPTY(1U) + +#define S_FLMRXFLSTEMPTY 29 +#define V_FLMRXFLSTEMPTY(x) ((x) << S_FLMRXFLSTEMPTY) +#define F_FLMRXFLSTEMPTY V_FLMRXFLSTEMPTY(1U) + #define A_TP_INT_CAUSE 0x474 #define A_TP_TX_MOD_Q1_Q0_RATE_LIMIT 0x8 @@ -1291,6 +1309,10 @@ #define A_ULPTX_CONFIG 0x580 +#define S_CFG_CQE_SOP_MASK 1 +#define V_CFG_CQE_SOP_MASK(x) ((x) << S_CFG_CQE_SOP_MASK) +#define F_CFG_CQE_SOP_MASK V_CFG_CQE_SOP_MASK(1U) + #define S_CFG_RR_ARB 0 #define V_CFG_RR_ARB(x) ((x) << S_CFG_RR_ARB) #define F_CFG_RR_ARB V_CFG_RR_ARB(1U) diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index c15e43a..666c317 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -91,6 +91,10 @@ struct rx_desc { struct tx_sw_desc { /* SW state per Tx descriptor */ struct sk_buff *skb; + u8 eop; /* set if last descriptor for packet */ + u8 addr_idx; /* buffer index of first SGL entry in descriptor */ + u8 fragidx; /* first page fragment associated with descriptor */ + s8 sflit; /* start flit of first SGL entry in descriptor */ }; struct rx_sw_desc { /* SW state per Rx descriptor */ @@ -109,13 +113,6 @@ struct rsp_desc { /* response queue descriptor */ u8 intr_gen; }; -struct unmap_info { /* packet unmapping info, overlays skb->cb */ - int sflit; /* start flit of first SGL entry in Tx descriptor */ - u16 fragidx; /* first page fragment in current Tx descriptor */ - u16 addr_idx; /* buffer index of first SGL entry in descriptor */ - u32 len; /* mapped length of skb main body */ -}; - /* * Holds unmapping information for Tx packets that need deferred unmapping. * This structure lives at skb->head and must be allocated by callers. @@ -177,6 +174,7 @@ static inline struct sge_qset *txq_to_qset(const struct sge_txq *q, int qidx) static inline void refill_rspq(struct adapter *adapter, const struct sge_rspq *q, unsigned int credits) { + rmb(); t3_write_reg(adapter, A_SG_RSPQ_CREDIT_RETURN, V_RSPQ(q->cntxt_id) | V_CREDITS(credits)); } @@ -209,32 +207,36 @@ static inline int need_skb_unmap(void) * * Unmap the main body of an sk_buff and its page fragments, if any. * Because of the fairly complicated structure of our SGLs and the desire - * to conserve space for metadata, we keep the information necessary to - * unmap an sk_buff partly in the sk_buff itself (in its cb), and partly - * in the Tx descriptors (the physical addresses of the various data - * buffers). The send functions initialize the state in skb->cb so we - * can unmap the buffers held in the first Tx descriptor here, and we - * have enough information at this point to update the state for the next - * Tx descriptor. + * to conserve space for metadata, the information necessary to unmap an + * sk_buff is spread across the sk_buff itself (buffer lengths), the HW Tx + * descriptors (the physical addresses of the various data buffers), and + * the SW descriptor state (assorted indices). The send functions + * initialize the indices for the first packet descriptor so we can unmap + * the buffers held in the first Tx descriptor here, and we have enough + * information at this point to set the state for the next Tx descriptor. + * + * Note that it is possible to clean up the first descriptor of a packet + * before the send routines have written the next descriptors, but this + * race does not cause any problem. We just end up writing the unmapping + * info for the descriptor first. */ static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q, unsigned int cidx, struct pci_dev *pdev) { const struct sg_ent *sgp; - struct unmap_info *ui = (struct unmap_info *)skb->cb; - int nfrags, frag_idx, curflit, j = ui->addr_idx; + struct tx_sw_desc *d = &q->sdesc[cidx]; + int nfrags, frag_idx, curflit, j = d->addr_idx; - sgp = (struct sg_ent *)&q->desc[cidx].flit[ui->sflit]; + sgp = (struct sg_ent *)&q->desc[cidx].flit[d->sflit]; + frag_idx = d->fragidx; - if (ui->len) { - pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]), ui->len, - PCI_DMA_TODEVICE); - ui->len = 0; /* so we know for next descriptor for this skb */ + if (frag_idx == 0 && skb_headlen(skb)) { + pci_unmap_single(pdev, be64_to_cpu(sgp->addr[0]), + skb_headlen(skb), PCI_DMA_TODEVICE); j = 1; } - frag_idx = ui->fragidx; - curflit = ui->sflit + 1 + j; + curflit = d->sflit + 1 + j; nfrags = skb_shinfo(skb)->nr_frags; while (frag_idx < nfrags && curflit < WR_FLITS) { @@ -250,10 +252,11 @@ static inline void unmap_skb(struct sk_buff *skb, struct sge_txq *q, frag_idx++; } - if (frag_idx < nfrags) { /* SGL continues into next Tx descriptor */ - ui->fragidx = frag_idx; - ui->addr_idx = j; - ui->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */ + if (frag_idx < nfrags) { /* SGL continues into next Tx descriptor */ + d = cidx + 1 == q->size ? q->sdesc : d + 1; + d->fragidx = frag_idx; + d->addr_idx = j; + d->sflit = curflit - WR_FLITS - j; /* sflit can be -1 */ } } @@ -281,7 +284,7 @@ static void free_tx_desc(struct adapter *adapter, struct sge_txq *q, if (d->skb) { /* an SGL is present */ if (need_unmap) unmap_skb(d->skb, q, cidx, pdev); - if (d->skb->priority == cidx) + if (d->eop) kfree_skb(d->skb); } ++d; @@ -456,7 +459,7 @@ nomem: q->alloc_failed++; } q->credits++; } - + wmb(); t3_write_reg(adap, A_SG_KDOORBELL, V_EGRCNTX(q->cntxt_id)); } @@ -912,15 +915,13 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb, sd->skb = skb; if (need_skb_unmap()) { - struct unmap_info *ui = (struct unmap_info *)skb->cb; - - ui->fragidx = 0; - ui->addr_idx = 0; - ui->sflit = flits; + sd->fragidx = 0; + sd->addr_idx = 0; + sd->sflit = flits; } if (likely(ndesc == 1)) { - skb->priority = pidx; + sd->eop = 1; wrp->wr_hi = htonl(F_WR_SOP | F_WR_EOP | V_WR_DATATYPE(1) | V_WR_SGLSFLT(flits)) | wr_hi; wmb(); @@ -948,6 +949,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb, fp += avail; d++; + sd->eop = 0; sd++; if (++pidx == q->size) { pidx = 0; @@ -966,7 +968,7 @@ static void write_wr_hdr_sgl(unsigned int ndesc, struct sk_buff *skb, wr_gen2(d, gen); flits = 1; } - skb->priority = pidx; + sd->eop = 1; wrp->wr_hi |= htonl(F_WR_EOP); wmb(); wp->wr_lo = htonl(V_WR_LEN(WR_FLITS) | V_WR_GEN(ogen)) | wr_lo; @@ -1051,8 +1053,6 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, sgp = ndesc == 1 ? (struct sg_ent *)&d->flit[flits] : sgl; sgl_flits = make_sgl(skb, sgp, skb->data, skb_headlen(skb), adap->pdev); - if (need_skb_unmap()) - ((struct unmap_info *)skb->cb)->len = skb_headlen(skb); write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, gen, htonl(V_WR_OP(FW_WROPCODE_TUNNEL_TX_PKT) | compl), @@ -1354,6 +1354,7 @@ static void restart_ctrlq(unsigned long data) } spin_unlock(&q->lock); + wmb(); t3_write_reg(qs->adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); } @@ -1380,13 +1381,14 @@ static void deferred_unmap_destructor(struct sk_buff *skb) const dma_addr_t *p; const struct skb_shared_info *si; const struct deferred_unmap_info *dui; - const struct unmap_info *ui = (struct unmap_info *)skb->cb; dui = (struct deferred_unmap_info *)skb->head; p = dui->addr; - if (ui->len) - pci_unmap_single(dui->pdev, *p++, ui->len, PCI_DMA_TODEVICE); + if (skb->tail - skb->transport_header) + pci_unmap_single(dui->pdev, *p++, + skb->tail - skb->transport_header, + PCI_DMA_TODEVICE); si = skb_shinfo(skb); for (i = 0; i < si->nr_frags; i++) @@ -1451,8 +1453,6 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb, if (need_skb_unmap()) { setup_deferred_unmapping(skb, adap->pdev, sgp, sgl_flits); skb->destructor = deferred_unmap_destructor; - ((struct unmap_info *)skb->cb)->len = (skb->tail - - skb->transport_header); } write_wr_hdr_sgl(ndesc, skb, d, pidx, q, sgl, flits, sgl_flits, @@ -1574,6 +1574,7 @@ static void restart_offloadq(unsigned long data) set_bit(TXQ_RUNNING, &q->flags); set_bit(TXQ_LAST_PKT_DB, &q->flags); #endif + wmb(); t3_write_reg(adap, A_SG_KDOORBELL, F_SELEGRCNTX | V_EGRCNTX(q->cntxt_id)); } @@ -1739,7 +1740,6 @@ static inline int rx_offload(struct t3cdev *tdev, struct sge_rspq *rq, struct sk_buff *skb, struct sk_buff *rx_gather[], unsigned int gather_idx) { - rq->offload_pkts++; skb_reset_mac_header(skb); skb_reset_network_header(skb); skb_reset_transport_header(skb); @@ -2033,6 +2033,7 @@ no_mem: if (eth) rx_eth(adap, q, skb, ethpad); else { + q->offload_pkts++; /* Preserve the RSS info in csum & priority */ skb->csum = rss_hi; skb->priority = rss_lo; diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 522834c..dfdda47 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -865,7 +865,7 @@ int t3_get_tp_version(struct adapter *adapter, u32 *vers) 1, 1, 5, 1); if (ret) return ret; - + *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1); return 0; @@ -896,7 +896,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load) major = G_TP_VERSION_MAJOR(vers); minor = G_TP_VERSION_MINOR(vers); - if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) + if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR) return 0; if (major != TP_VERSION_MAJOR) @@ -913,7 +913,7 @@ int t3_check_tpsram_version(struct adapter *adapter, int *must_load) } /** - * t3_check_tpsram - check if provided protocol SRAM + * t3_check_tpsram - check if provided protocol SRAM * is compatible with this driver * @adapter: the adapter * @tp_sram: the firmware image to write @@ -988,13 +988,17 @@ int t3_check_fw_version(struct adapter *adapter, int *must_load) CH_ERR(adapter, "found wrong FW version(%u.%u), " "driver needs version %u.%u\n", major, minor, FW_VERSION_MAJOR, FW_VERSION_MINOR); - else { + else if (minor < FW_VERSION_MINOR) { *must_load = 0; - CH_WARN(adapter, "found wrong FW minor version(%u.%u), " + CH_WARN(adapter, "found old FW minor version(%u.%u), " "driver compiled for version %u.%u\n", major, minor, FW_VERSION_MAJOR, FW_VERSION_MINOR); + } else { + CH_WARN(adapter, "found newer FW version(%u.%u), " + "driver compiled for version %u.%u\n", major, minor, + FW_VERSION_MAJOR, FW_VERSION_MINOR); + return 0; } - return -EINVAL; } @@ -1276,7 +1280,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, #define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\ F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \ /* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \ - V_BISTERR(M_BISTERR) | F_PEXERR) + V_BISTERR(M_BISTERR)) #define ULPRX_INTR_MASK F_PARERR #define ULPTX_INTR_MASK 0 #define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \ @@ -1379,8 +1383,16 @@ static void tp_intr_handler(struct adapter *adapter) {0} }; + static struct intr_info tp_intr_info_t3c[] = { + { 0x1ffffff, "TP parity error", -1, 1 }, + { F_FLMRXFLSTEMPTY, "TP out of Rx pages", -1, 1 }, + { F_FLMTXFLSTEMPTY, "TP out of Tx pages", -1, 1 }, + { 0 } + }; + if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff, - tp_intr_info, NULL)) + adapter->params.rev < T3_REV_C ? + tp_intr_info : tp_intr_info_t3c, NULL)) t3_fatal_err(adapter); } @@ -1730,7 +1742,6 @@ void t3_intr_enable(struct adapter *adapter) MC7_INTR_MASK}, {A_MC5_DB_INT_ENABLE, MC5_INTR_MASK}, {A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK}, - {A_TP_INT_ENABLE, 0x3bfffff}, {A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK}, {A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK}, {A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK}, @@ -1740,6 +1751,8 @@ void t3_intr_enable(struct adapter *adapter) adapter->slow_intr_mask = PL_INTR_MASK; t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0); + t3_write_reg(adapter, A_TP_INT_ENABLE, + adapter->params.rev >= T3_REV_C ? 0x2bfffff : 0x3bfffff); if (adapter->params.rev > 0) { t3_write_reg(adapter, A_CPL_INTR_ENABLE, @@ -2495,7 +2508,7 @@ static void tp_config(struct adapter *adap, const struct tp_params *p) t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0); t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080); t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000); - + if (adap->params.rev > 0) { tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE); t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO, @@ -2505,6 +2518,11 @@ static void tp_config(struct adapter *adap, const struct tp_params *p) } else t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED); + if (adap->params.rev == T3_REV_C) + t3_set_reg_field(adap, A_TP_PC_CONFIG, + V_TABLELATENCYDELTA(M_TABLELATENCYDELTA), + V_TABLELATENCYDELTA(4)); + t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0); t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0); t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0); @@ -2817,7 +2835,7 @@ int t3_set_proto_sram(struct adapter *adap, u8 *data) t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++)); t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++)); t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++)); - + t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31); if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1)) return -EIO; @@ -3242,6 +3260,10 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params) else t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN); + if (adapter->params.rev == T3_REV_C) + t3_set_reg_field(adapter, A_ULPTX_CONFIG, 0, + F_CFG_CQE_SOP_MASK); + t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff); t3_write_reg(adapter, A_PM1_RX_MODE, 0); t3_write_reg(adapter, A_PM1_TX_MODE, 0); @@ -3403,13 +3425,13 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai) } /* - * Reset the adapter. + * Reset the adapter. * Older PCIe cards lose their config space during reset, PCI-X * ones don't. */ static int t3_reset_adapter(struct adapter *adapter) { - int i, save_and_restore_pcie = + int i, save_and_restore_pcie = adapter->params.rev < T3_REV_B2 && is_pcie(adapter); uint16_t devid = 0; diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h index ef1c633..229303f 100644 --- a/drivers/net/cxgb3/version.h +++ b/drivers/net/cxgb3/version.h @@ -38,7 +38,7 @@ #define DRV_VERSION "1.0-ko" /* Firmware version */ -#define FW_VERSION_MAJOR 4 -#define FW_VERSION_MINOR 6 +#define FW_VERSION_MAJOR 5 +#define FW_VERSION_MINOR 0 #define FW_VERSION_MICRO 0 #endif /* __CHELSIO_VERSION_H */ diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c index efcf09a..ffdc0a1 100644 --- a/drivers/net/cxgb3/xgmac.c +++ b/drivers/net/cxgb3/xgmac.c @@ -153,7 +153,7 @@ static int t3b2_mac_reset(struct cmac *mac) unsigned int oft = mac->offset; u32 val; - if (!macidx(mac)) + if (!macidx(mac)) t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0); else t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0); @@ -187,11 +187,11 @@ static int t3b2_mac_reset(struct cmac *mac) msleep(1); t3b_pcs_reset(mac); } - t3_write_reg(adap, A_XGM_RX_CFG + oft, + t3_write_reg(adap, A_XGM_RX_CFG + oft, F_DISPAUSEFRAMES | F_EN1536BFRAMES | F_RMFCS | F_ENJUMBO | F_ENHASHMCAST); - if (!macidx(mac)) + if (!macidx(mac)) t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE); else t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE); @@ -336,7 +336,7 @@ int t3_mac_set_mtu(struct cmac *mac, unsigned int mtu) * Adjust the PAUSE frame watermarks. We always set the LWM, and the * HWM only if flow-control is enabled. */ - hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, + hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE * 38 / 100); hwm = min(hwm, MAC_RXFIFO_SIZE - 8192); lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4); @@ -449,7 +449,7 @@ int t3_mac_enable(struct cmac *mac, int which) struct adapter *adap = mac->adapter; unsigned int oft = mac->offset; struct mac_stats *s = &mac->stats; - + if (which & MAC_DIRECTION_TX) { t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401); diff --git a/drivers/net/declance.c b/drivers/net/declance.c index 00e0194..6b1e77c 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -719,15 +719,15 @@ out: spin_unlock(&lp->lock); } -static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id) +static irqreturn_t lance_dma_merr_int(int irq, void *dev_id) { struct net_device *dev = dev_id; - printk("%s: DMA error\n", dev->name); + printk(KERN_ERR "%s: DMA error\n", dev->name); return IRQ_HANDLED; } -static irqreturn_t lance_interrupt(const int irq, void *dev_id) +static irqreturn_t lance_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; struct lance_private *lp = netdev_priv(dev); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index e1c8a0d..27f4d4a 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -106,6 +106,13 @@ * the RFD, the RFD must be dma_sync'ed to maintain a consistent * view from software and hardware. * + * In order to keep updates to the RFD link field from colliding with + * hardware writes to mark packets complete, we use the feature that + * hardware will not write to a size 0 descriptor and mark the previous + * packet as end-of-list (EL). After updating the link, we remove EL + * and only then restore the size such that hardware may use the + * previous-to-end RFD. + * * Under typical operation, the receive unit (RU) is start once, * and the controller happily fills RFDs as frames arrive. If * replacement RFDs cannot be allocated, or the RU goes non-active, @@ -281,6 +288,7 @@ struct csr { }; enum scb_status { + rus_no_res = 0x08, rus_ready = 0x10, rus_mask = 0x3C, }; @@ -952,7 +960,7 @@ static void e100_get_defaults(struct nic *nic) ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i)); /* Template for a freshly allocated RFD */ - nic->blank_rfd.command = cpu_to_le16(cb_el); + nic->blank_rfd.command = 0; nic->blank_rfd.rbd = 0xFFFFFFFF; nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN); @@ -1791,15 +1799,12 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) } /* Link the RFD to end of RFA by linking previous RFD to - * this one, and clearing EL bit of previous. */ + * this one. We are safe to touch the previous RFD because + * it is protected by the before last buffer's el bit being set */ if(rx->prev->skb) { struct rfd *prev_rfd = (struct rfd *)rx->prev->skb->data; put_unaligned(cpu_to_le32(rx->dma_addr), (u32 *)&prev_rfd->link); - wmb(); - prev_rfd->command &= ~cpu_to_le16(cb_el); - pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr, - sizeof(struct rfd), PCI_DMA_TODEVICE); } return 0; @@ -1824,8 +1829,19 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status); /* If data isn't ready, nothing to indicate */ - if(unlikely(!(rfd_status & cb_complete))) + if (unlikely(!(rfd_status & cb_complete))) { + /* If the next buffer has the el bit, but we think the receiver + * is still running, check to see if it really stopped while + * we had interrupts off. + * This allows for a fast restart without re-enabling + * interrupts */ + if ((le16_to_cpu(rfd->command) & cb_el) && + (RU_RUNNING == nic->ru_running)) + + if (readb(&nic->csr->scb.status) & rus_no_res) + nic->ru_running = RU_SUSPENDED; return -ENODATA; + } /* Get actual data size */ actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF; @@ -1836,9 +1852,18 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx, pci_unmap_single(nic->pdev, rx->dma_addr, RFD_BUF_LEN, PCI_DMA_FROMDEVICE); - /* this allows for a fast restart without re-enabling interrupts */ - if(le16_to_cpu(rfd->command) & cb_el) + /* If this buffer has the el bit, but we think the receiver + * is still running, check to see if it really stopped while + * we had interrupts off. + * This allows for a fast restart without re-enabling interrupts. + * This can happen when the RU sees the size change but also sees + * the el bit set. */ + if ((le16_to_cpu(rfd->command) & cb_el) && + (RU_RUNNING == nic->ru_running)) { + + if (readb(&nic->csr->scb.status) & rus_no_res) nic->ru_running = RU_SUSPENDED; + } /* Pull off the RFD and put the actual data (minus eth hdr) */ skb_reserve(skb, sizeof(struct rfd)); @@ -1870,31 +1895,30 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, unsigned int work_to_do) { struct rx *rx; - int restart_required = 0; - struct rx *rx_to_start = NULL; - - /* are we already rnr? then pay attention!!! this ensures that - * the state machine progression never allows a start with a - * partially cleaned list, avoiding a race between hardware - * and rx_to_clean when in NAPI mode */ - if(RU_SUSPENDED == nic->ru_running) - restart_required = 1; + int restart_required = 0, err = 0; + struct rx *old_before_last_rx, *new_before_last_rx; + struct rfd *old_before_last_rfd, *new_before_last_rfd; /* Indicate newly arrived packets */ for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { - int err = e100_rx_indicate(nic, rx, work_done, work_to_do); - if(-EAGAIN == err) { - /* hit quota so have more work to do, restart once - * cleanup is complete */ - restart_required = 0; + err = e100_rx_indicate(nic, rx, work_done, work_to_do); + /* Hit quota or no more to clean */ + if (-EAGAIN == err || -ENODATA == err) break; - } else if(-ENODATA == err) - break; /* No more to clean */ } - /* save our starting point as the place we'll restart the receiver */ - if(restart_required) - rx_to_start = nic->rx_to_clean; + + /* On EAGAIN, hit quota so have more work to do, restart once + * cleanup is complete. + * Else, are we already rnr? then pay attention!!! this ensures that + * the state machine progression never allows a start with a + * partially cleaned list, avoiding a race between hardware + * and rx_to_clean when in NAPI mode */ + if (-EAGAIN != err && RU_SUSPENDED == nic->ru_running) + restart_required = 1; + + old_before_last_rx = nic->rx_to_use->prev->prev; + old_before_last_rfd = (struct rfd *)old_before_last_rx->skb->data; /* Alloc new skbs to refill list */ for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { @@ -1902,10 +1926,42 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, break; /* Better luck next time (see watchdog) */ } + new_before_last_rx = nic->rx_to_use->prev->prev; + if (new_before_last_rx != old_before_last_rx) { + /* Set the el-bit on the buffer that is before the last buffer. + * This lets us update the next pointer on the last buffer + * without worrying about hardware touching it. + * We set the size to 0 to prevent hardware from touching this + * buffer. + * When the hardware hits the before last buffer with el-bit + * and size of 0, it will RNR interrupt, the RUS will go into + * the No Resources state. It will not complete nor write to + * this buffer. */ + new_before_last_rfd = + (struct rfd *)new_before_last_rx->skb->data; + new_before_last_rfd->size = 0; + new_before_last_rfd->command |= cpu_to_le16(cb_el); + pci_dma_sync_single_for_device(nic->pdev, + new_before_last_rx->dma_addr, sizeof(struct rfd), + PCI_DMA_TODEVICE); + + /* Now that we have a new stopping point, we can clear the old + * stopping point. We must sync twice to get the proper + * ordering on the hardware side of things. */ + old_before_last_rfd->command &= ~cpu_to_le16(cb_el); + pci_dma_sync_single_for_device(nic->pdev, + old_before_last_rx->dma_addr, sizeof(struct rfd), + PCI_DMA_TODEVICE); + old_before_last_rfd->size = cpu_to_le16(VLAN_ETH_FRAME_LEN); + pci_dma_sync_single_for_device(nic->pdev, + old_before_last_rx->dma_addr, sizeof(struct rfd), + PCI_DMA_TODEVICE); + } + if(restart_required) { // ack the rnr? writeb(stat_ack_rnr, &nic->csr->scb.stat_ack); - e100_start_receiver(nic, rx_to_start); + e100_start_receiver(nic, nic->rx_to_clean); if(work_done) (*work_done)++; } @@ -1937,6 +1993,7 @@ static int e100_rx_alloc_list(struct nic *nic) { struct rx *rx; unsigned int i, count = nic->params.rfds.count; + struct rfd *before_last; nic->rx_to_use = nic->rx_to_clean = NULL; nic->ru_running = RU_UNINITIALIZED; @@ -1952,6 +2009,19 @@ static int e100_rx_alloc_list(struct nic *nic) return -ENOMEM; } } + /* Set the el-bit on the buffer that is before the last buffer. + * This lets us update the next pointer on the last buffer without + * worrying about hardware touching it. + * We set the size to 0 to prevent hardware from touching this buffer. + * When the hardware hits the before last buffer with el-bit and size + * of 0, it will RNR interrupt, the RU will go into the No Resources + * state. It will not complete nor write to this buffer. */ + rx = nic->rxs->prev->prev; + before_last = (struct rfd *)rx->skb->data; + before_last->command |= cpu_to_le16(cb_el); + before_last->size = 0; + pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr, + sizeof(struct rfd), PCI_DMA_TODEVICE); nic->rx_to_use = nic->rx_to_clean = nic->rxs; nic->ru_running = RU_SUSPENDED; @@ -2370,7 +2440,7 @@ static const char e100_gstrings_test[][ETH_GSTRING_LEN] = { "Mac loopback (offline)", "Phy loopback (offline)", }; -#define E100_TEST_LEN sizeof(e100_gstrings_test) / ETH_GSTRING_LEN +#define E100_TEST_LEN ARRAY_SIZE(e100_gstrings_test) static void e100_diag_test(struct net_device *netdev, struct ethtool_test *test, u64 *data) @@ -2432,7 +2502,7 @@ static const char e100_gstrings_stats[][ETH_GSTRING_LEN] = { "rx_flow_control_unsupported", "tx_tco_packets", "rx_tco_packets", }; #define E100_NET_STATS_LEN 21 -#define E100_STATS_LEN sizeof(e100_gstrings_stats) / ETH_GSTRING_LEN +#define E100_STATS_LEN ARRAY_SIZE(e100_gstrings_stats) static int e100_get_sset_count(struct net_device *netdev, int sset) { diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index b83ccce..d876787 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -110,7 +110,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = { "Interrupt test (offline)", "Loopback test (offline)", "Link test (on/offline)" }; -#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN +#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test) static int e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) @@ -728,39 +728,65 @@ err_setup: return err; } -#define REG_PATTERN_TEST(R, M, W) \ -{ \ - uint32_t pat, val; \ - const uint32_t test[] = \ - {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for (pat = 0; pat < ARRAY_SIZE(test); pat++) { \ - E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \ - val = E1000_READ_REG(&adapter->hw, R); \ - if (val != (test[pat] & W & M)) { \ - DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \ - "0x%08X expected 0x%08X\n", \ - E1000_##R, val, (test[pat] & W & M)); \ - *data = (adapter->hw.mac_type < e1000_82543) ? \ - E1000_82542_##R : E1000_##R; \ - return 1; \ - } \ - } \ +static bool reg_pattern_test(struct e1000_adapter *adapter, uint64_t *data, + int reg, uint32_t mask, uint32_t write) +{ + static const uint32_t test[] = + {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + uint8_t __iomem *address = adapter->hw.hw_addr + reg; + uint32_t read; + int i; + + for (i = 0; i < ARRAY_SIZE(test); i++) { + writel(write & test[i], address); + read = readl(address); + if (read != (write & test[i] & mask)) { + DPRINTK(DRV, ERR, "pattern test reg %04X failed: " + "got 0x%08X expected 0x%08X\n", + reg, read, (write & test[i] & mask)); + *data = reg; + return true; + } + } + return false; } -#define REG_SET_AND_CHECK(R, M, W) \ -{ \ - uint32_t val; \ - E1000_WRITE_REG(&adapter->hw, R, W & M); \ - val = E1000_READ_REG(&adapter->hw, R); \ - if ((W & M) != (val & M)) { \ - DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\ - "expected 0x%08X\n", E1000_##R, (val & M), (W & M)); \ - *data = (adapter->hw.mac_type < e1000_82543) ? \ - E1000_82542_##R : E1000_##R; \ - return 1; \ - } \ +static bool reg_set_and_check(struct e1000_adapter *adapter, uint64_t *data, + int reg, uint32_t mask, uint32_t write) +{ + uint8_t __iomem *address = adapter->hw.hw_addr + reg; + uint32_t read; + + writel(write & mask, address); + read = readl(address); + if ((read & mask) != (write & mask)) { + DPRINTK(DRV, ERR, "set/check reg %04X test failed: " + "got 0x%08X expected 0x%08X\n", + reg, (read & mask), (write & mask)); + *data = reg; + return true; + } + return false; } +#define REG_PATTERN_TEST(reg, mask, write) \ + do { \ + if (reg_pattern_test(adapter, data, \ + (adapter->hw.mac_type >= e1000_82543) \ + ? E1000_##reg : E1000_82542_##reg, \ + mask, write)) \ + return 1; \ + } while (0) + +#define REG_SET_AND_CHECK(reg, mask, write) \ + do { \ + if (reg_set_and_check(adapter, data, \ + (adapter->hw.mac_type >= e1000_82543) \ + ? E1000_##reg : E1000_82542_##reg, \ + mask, write)) \ + return 1; \ + } while (0) + static int e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data) { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4f37506..724f067 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -73,14 +73,6 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1026), INTEL_E1000_ETHERNET_DEVICE(0x1027), INTEL_E1000_ETHERNET_DEVICE(0x1028), - INTEL_E1000_ETHERNET_DEVICE(0x1049), - INTEL_E1000_ETHERNET_DEVICE(0x104A), - INTEL_E1000_ETHERNET_DEVICE(0x104B), - INTEL_E1000_ETHERNET_DEVICE(0x104C), - INTEL_E1000_ETHERNET_DEVICE(0x104D), - INTEL_E1000_ETHERNET_DEVICE(0x105E), - INTEL_E1000_ETHERNET_DEVICE(0x105F), - INTEL_E1000_ETHERNET_DEVICE(0x1060), INTEL_E1000_ETHERNET_DEVICE(0x1075), INTEL_E1000_ETHERNET_DEVICE(0x1076), INTEL_E1000_ETHERNET_DEVICE(0x1077), @@ -89,28 +81,9 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x107A), INTEL_E1000_ETHERNET_DEVICE(0x107B), INTEL_E1000_ETHERNET_DEVICE(0x107C), - INTEL_E1000_ETHERNET_DEVICE(0x107D), - INTEL_E1000_ETHERNET_DEVICE(0x107E), - INTEL_E1000_ETHERNET_DEVICE(0x107F), INTEL_E1000_ETHERNET_DEVICE(0x108A), - INTEL_E1000_ETHERNET_DEVICE(0x108B), - INTEL_E1000_ETHERNET_DEVICE(0x108C), - INTEL_E1000_ETHERNET_DEVICE(0x1096), - INTEL_E1000_ETHERNET_DEVICE(0x1098), INTEL_E1000_ETHERNET_DEVICE(0x1099), - INTEL_E1000_ETHERNET_DEVICE(0x109A), - INTEL_E1000_ETHERNET_DEVICE(0x10A4), - INTEL_E1000_ETHERNET_DEVICE(0x10A5), INTEL_E1000_ETHERNET_DEVICE(0x10B5), - INTEL_E1000_ETHERNET_DEVICE(0x10B9), - INTEL_E1000_ETHERNET_DEVICE(0x10BA), - INTEL_E1000_ETHERNET_DEVICE(0x10BB), - INTEL_E1000_ETHERNET_DEVICE(0x10BC), - INTEL_E1000_ETHERNET_DEVICE(0x10C4), - INTEL_E1000_ETHERNET_DEVICE(0x10C5), - INTEL_E1000_ETHERNET_DEVICE(0x10D5), - INTEL_E1000_ETHERNET_DEVICE(0x10D9), - INTEL_E1000_ETHERNET_DEVICE(0x10DA), /* required last entry */ {0,} }; @@ -153,7 +126,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring); static void e1000_clean_rx_ring(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring); -static void e1000_set_multi(struct net_device *netdev); +static void e1000_set_rx_mode(struct net_device *netdev); static void e1000_update_phy_info(unsigned long data); static void e1000_watchdog(unsigned long data); static void e1000_82547_tx_fifo_stall(unsigned long data); @@ -514,7 +487,7 @@ static void e1000_configure(struct e1000_adapter *adapter) struct net_device *netdev = adapter->netdev; int i; - e1000_set_multi(netdev); + e1000_set_rx_mode(netdev); e1000_restore_vlan(adapter); e1000_init_manageability(adapter); @@ -926,7 +899,7 @@ e1000_probe(struct pci_dev *pdev, netdev->stop = &e1000_close; netdev->hard_start_xmit = &e1000_xmit_frame; netdev->get_stats = &e1000_get_stats; - netdev->set_multicast_list = &e1000_set_multi; + netdev->set_rx_mode = &e1000_set_rx_mode; netdev->set_mac_address = &e1000_set_mac; netdev->change_mtu = &e1000_change_mtu; netdev->do_ioctl = &e1000_ioctl; @@ -2409,21 +2382,22 @@ e1000_set_mac(struct net_device *netdev, void *p) } /** - * e1000_set_multi - Multicast and Promiscuous mode set + * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set * @netdev: network interface device structure * - * The set_multi entry point is called whenever the multicast address - * list or the network interface flags are updated. This routine is - * responsible for configuring the hardware for proper multicast, + * The set_rx_mode entry point is called whenever the unicast or multicast + * address lists or the network interface flags are updated. This routine is + * responsible for configuring the hardware for proper unicast, multicast, * promiscuous mode, and all-multi behavior. **/ static void -e1000_set_multi(struct net_device *netdev) +e1000_set_rx_mode(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - struct dev_mc_list *mc_ptr; + struct dev_addr_list *uc_ptr; + struct dev_addr_list *mc_ptr; uint32_t rctl; uint32_t hash_value; int i, rar_entries = E1000_RAR_ENTRIES; @@ -2446,9 +2420,16 @@ e1000_set_multi(struct net_device *netdev) rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); } else if (netdev->flags & IFF_ALLMULTI) { rctl |= E1000_RCTL_MPE; - rctl &= ~E1000_RCTL_UPE; } else { - rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); + rctl &= ~E1000_RCTL_MPE; + } + + uc_ptr = NULL; + if (netdev->uc_count > rar_entries - 1) { + rctl |= E1000_RCTL_UPE; + } else if (!(netdev->flags & IFF_PROMISC)) { + rctl &= ~E1000_RCTL_UPE; + uc_ptr = netdev->uc_list; } E1000_WRITE_REG(hw, RCTL, rctl); @@ -2458,7 +2439,10 @@ e1000_set_multi(struct net_device *netdev) if (hw->mac_type == e1000_82542_rev2_0) e1000_enter_82542_rst(adapter); - /* load the first 14 multicast address into the exact filters 1-14 + /* load the first 14 addresses into the exact filters 1-14. Unicast + * addresses take precedence to avoid disabling unicast filtering + * when possible. + * * RAR 0 is used for the station MAC adddress * if there are not 14 addresses, go ahead and clear the filters * -- with 82571 controllers only 0-13 entries are filled here @@ -2466,8 +2450,11 @@ e1000_set_multi(struct net_device *netdev) mc_ptr = netdev->mc_list; for (i = 1; i < rar_entries; i++) { - if (mc_ptr) { - e1000_rar_set(hw, mc_ptr->dmi_addr, i); + if (uc_ptr) { + e1000_rar_set(hw, uc_ptr->da_addr, i); + uc_ptr = uc_ptr->next; + } else if (mc_ptr) { + e1000_rar_set(hw, mc_ptr->da_addr, i); mc_ptr = mc_ptr->next; } else { E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); @@ -2476,6 +2463,7 @@ e1000_set_multi(struct net_device *netdev) E1000_WRITE_FLUSH(hw); } } + WARN_ON(uc_ptr != NULL); /* clear the old settings from the multicast hash table */ @@ -2487,7 +2475,7 @@ e1000_set_multi(struct net_device *netdev) /* load any remaining addresses into the hash table */ for (; mc_ptr; mc_ptr = mc_ptr->next) { - hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr); + hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); e1000_mta_set(hw, hash_value); } @@ -3679,10 +3667,6 @@ e1000_update_stats(struct e1000_adapter *adapter) } /* Fill out the OS statistics structure */ - adapter->net_stats.rx_packets = adapter->stats.gprc; - adapter->net_stats.tx_packets = adapter->stats.gptc; - adapter->net_stats.rx_bytes = adapter->stats.gorcl; - adapter->net_stats.tx_bytes = adapter->stats.gotcl; adapter->net_stats.multicast = adapter->stats.mprc; adapter->net_stats.collisions = adapter->stats.colc; @@ -4061,6 +4045,8 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, } adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_packets += total_tx_packets; + adapter->net_stats.tx_bytes += total_tx_bytes; + adapter->net_stats.tx_packets += total_tx_packets; return cleaned; } @@ -4283,6 +4269,8 @@ next_desc: adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; + adapter->net_stats.rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; return cleaned; } @@ -4470,6 +4458,8 @@ next_desc: adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; + adapter->net_stats.rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; return cleaned; } @@ -5097,7 +5087,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if (wufc) { e1000_setup_rctl(adapter); - e1000_set_multi(netdev); + e1000_set_rx_mode(netdev); /* turn on all-multi mode if wake on multicast is enabled */ if (wufc & E1000_WUFC_MC) { diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 14141a5..3beace5 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -194,6 +194,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) break; case E1000_DEV_ID_82571EB_SERDES: case E1000_DEV_ID_82572EI_SERDES: + case E1000_DEV_ID_82571EB_SERDES_DUAL: + case E1000_DEV_ID_82571EB_SERDES_QUAD: hw->media_type = e1000_media_type_internal_serdes; break; default: @@ -260,6 +262,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter) case E1000_DEV_ID_82571EB_QUAD_COPPER: case E1000_DEV_ID_82571EB_QUAD_FIBER: case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: + case E1000_DEV_ID_82571PT_QUAD_COPPER: adapter->flags |= FLAG_IS_QUAD_PORT; /* mark the first port */ if (global_quad_port_a == 0) @@ -285,6 +288,9 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter) if (adapter->flags & FLAG_IS_QUAD_PORT && (!(adapter->flags & FLAG_IS_QUAD_PORT_A))) adapter->flags &= ~FLAG_HAS_WOL; + /* Does not support WoL on any port */ + if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) + adapter->flags &= ~FLAG_HAS_WOL; break; case e1000_82573: @@ -752,6 +758,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ew32(IMC, 0xffffffff); icr = er32(ICR); + if (hw->mac.type == e1000_82571 && + hw->dev_spec.e82571.alt_mac_addr_is_present) + e1000e_set_laa_state_82571(hw, true); + return 0; } @@ -1339,7 +1349,6 @@ struct e1000_info e1000_82573_info = { | FLAG_HAS_STATS_ICR_ICT | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT - | FLAG_HAS_ASPM | FLAG_HAS_ERT | FLAG_HAS_SWSM_ON_LOAD, .pba = 20, diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index b32ed45..f2175ea 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -557,6 +557,7 @@ #define NVM_INIT_3GIO_3 0x001A #define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_CFG 0x0012 +#define NVM_ALT_MAC_ADDR_PTR 0x0037 #define NVM_CHECKSUM_REG 0x003F #define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 473f78d..8b88c22 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -288,7 +288,6 @@ struct e1000_info { #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) -#define FLAG_HAS_ASPM (1 << 8) #define FLAG_HAS_STATS_ICR_ICT (1 << 9) #define FLAG_HAS_STATS_PTC_PRC (1 << 10) #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 87f9da1..6d9c27f 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -95,15 +95,14 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "tx_dma_failed", E1000_STAT(tx_dma_failed) }, }; -#define E1000_GLOBAL_STATS_LEN \ - sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) +#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) #define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN) static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = { "Register test (offline)", "Eeprom test (offline)", "Interrupt test (offline)", "Loopback test (offline)", "Link test (on/offline)" }; -#define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN +#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test) static int e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) @@ -691,41 +690,63 @@ err_setup: return err; } -#define REG_PATTERN_TEST(R, M, W) REG_PATTERN_TEST_ARRAY(R, 0, M, W) -#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, writeable) \ -{ \ - u32 _pat; \ - u32 _value; \ - u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ - for (_pat = 0; _pat < ARRAY_SIZE(_test); _pat++) { \ - E1000_WRITE_REG_ARRAY(hw, reg, offset, \ - (_test[_pat] & writeable)); \ - _value = E1000_READ_REG_ARRAY(hw, reg, offset); \ - if (_value != (_test[_pat] & writeable & mask)) { \ - ndev_err(netdev, "pattern test reg %04X " \ - "failed: got 0x%08X expected 0x%08X\n", \ - reg + offset, \ - value, (_test[_pat] & writeable & mask)); \ - *data = reg; \ - return 1; \ - } \ - } \ +bool reg_pattern_test_array(struct e1000_adapter *adapter, u64 *data, + int reg, int offset, u32 mask, u32 write) +{ + int i; + u32 read; + static const u32 test[] = + {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; + for (i = 0; i < ARRAY_SIZE(test); i++) { + E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, + (test[i] & write)); + read = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); + if (read != (test[i] & write & mask)) { + ndev_err(adapter->netdev, "pattern test reg %04X " + "failed: got 0x%08X expected 0x%08X\n", + reg + offset, + read, (test[i] & write & mask)); + *data = reg; + return true; + } + } + return false; } -#define REG_SET_AND_CHECK(R, M, W) \ -{ \ - u32 _value; \ - __ew32(hw, R, W & M); \ - _value = __er32(hw, R); \ - if ((W & M) != (_value & M)) { \ - ndev_err(netdev, "set/check reg %04X test failed: " \ - "got 0x%08X expected 0x%08X\n", R, (_value & M), \ - (W & M)); \ - *data = R; \ - return 1; \ - } \ +static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, + int reg, u32 mask, u32 write) +{ + u32 read; + __ew32(&adapter->hw, reg, write & mask); + read = __er32(&adapter->hw, reg); + if ((write & mask) != (read & mask)) { + ndev_err(adapter->netdev, "set/check reg %04X test failed: " + "got 0x%08X expected 0x%08X\n", reg, (read & mask), + (write & mask)); + *data = reg; + return true; + } + return false; } +#define REG_PATTERN_TEST(R, M, W) \ + do { \ + if (reg_pattern_test_array(adapter, data, R, 0, M, W)) \ + return 1; \ + } while (0) + +#define REG_PATTERN_TEST_ARRAY(R, offset, M, W) \ + do { \ + if (reg_pattern_test_array(adapter, data, R, offset, M, W)) \ + return 1; \ + } while (0) + +#define REG_SET_AND_CHECK(R, M, W) \ + do { \ + if (reg_set_and_check(adapter, data, R, M, W)) \ + return 1; \ + } while (0) + static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) { struct e1000_hw *hw = &adapter->hw; diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 6451578..71f93ce 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -303,8 +303,11 @@ enum e1e_registers { #define E1000_DEV_ID_82571EB_FIBER 0x105F #define E1000_DEV_ID_82571EB_SERDES 0x1060 #define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 +#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 #define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 #define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC +#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9 +#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA #define E1000_DEV_ID_82572EI_COPPER 0x107D #define E1000_DEV_ID_82572EI_FIBER 0x107E #define E1000_DEV_ID_82572EI_SERDES 0x107F @@ -816,6 +819,7 @@ struct e1000_bus_info { struct e1000_dev_spec_82571 { bool laa_is_present; + bool alt_mac_addr_is_present; }; struct e1000_shadow_ram { diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 0bdeca3..16f35fa 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw) { s32 ret_val; u16 offset, nvm_data, i; + u16 mac_addr_offset = 0; + + if (hw->mac.type == e1000_82571) { + /* Check for an alternate MAC address. An alternate MAC + * address can be setup by pre-boot software and must be + * treated like a permanent address and must override the + * actual permanent MAC address. */ + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, + &mac_addr_offset); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + if (mac_addr_offset == 0xFFFF) + mac_addr_offset = 0; + + if (mac_addr_offset) { + if (hw->bus.func == E1000_FUNC_1) + mac_addr_offset += ETH_ALEN/sizeof(u16); + + /* make sure we have a valid mac address here + * before using it */ + ret_val = e1000_read_nvm(hw, mac_addr_offset, 1, + &nvm_data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + if (nvm_data & 0x0001) + mac_addr_offset = 0; + } + + if (mac_addr_offset) + hw->dev_spec.e82571.alt_mac_addr_is_present = 1; + } for (i = 0; i < ETH_ALEN; i += 2) { - offset = i >> 1; + offset = mac_addr_offset + (i >> 1); ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); if (ret_val) { hw_dbg(hw, "NVM Read Error\n"); @@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw) } /* Flip last bit of mac address if we're on second port */ - if (hw->bus.func == E1000_FUNC_1) + if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1) hw->mac.perm_addr[5] ^= 1; for (i = 0; i < ETH_ALEN; i++) diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 4fd2e23..6c99703 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -458,6 +458,8 @@ next_desc: adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; + adapter->net_stats.rx_bytes += total_rx_bytes; return cleaned; } @@ -593,6 +595,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } adapter->total_tx_bytes += total_tx_bytes; adapter->total_tx_packets += total_tx_packets; + adapter->net_stats.tx_packets += total_tx_packets; + adapter->net_stats.tx_bytes += total_tx_bytes; return cleaned; } @@ -755,6 +759,8 @@ next_desc: adapter->total_rx_packets += total_rx_packets; adapter->total_rx_bytes += total_rx_bytes; + adapter->net_stats.rx_packets += total_rx_packets; + adapter->net_stats.rx_bytes += total_rx_bytes; return cleaned; } @@ -2537,10 +2543,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter) } /* Fill out the OS statistics structure */ - adapter->net_stats.rx_packets = adapter->stats.gprc; - adapter->net_stats.tx_packets = adapter->stats.gptc; - adapter->net_stats.rx_bytes = adapter->stats.gorcl; - adapter->net_stats.tx_bytes = adapter->stats.gotcl; adapter->net_stats.multicast = adapter->stats.mprc; adapter->net_stats.collisions = adapter->stats.colc; @@ -3511,6 +3513,33 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } +static void e1000e_disable_l1aspm(struct pci_dev *pdev) +{ + int pos; + u32 cap; + u16 val; + + /* + * 82573 workaround - disable L1 ASPM on mobile chipsets + * + * L1 ASPM on various mobile (ich7) chipsets do not behave properly + * resulting in lost data or garbage information on the pci-e link + * level. This could result in (false) bad EEPROM checksum errors, + * long ping times (up to 2s) or even a system freeze/hang. + * + * Unfortunately this feature saves about 1W power consumption when + * active. + */ + pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); + pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, &cap); + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, &val); + if (val & 0x2) { + dev_warn(&pdev->dev, "Disabling L1 ASPM\n"); + val &= ~0x2; + pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, val); + } +} + #ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev) { @@ -3521,6 +3550,7 @@ static int e1000_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); + e1000e_disable_l1aspm(pdev); err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, @@ -3621,6 +3651,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; + e1000e_disable_l1aspm(pdev); if (pci_enable_device(pdev)) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset.\n"); @@ -3722,6 +3753,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, u16 eeprom_data = 0; u16 eeprom_apme_mask = E1000_EEPROM_APME; + e1000e_disable_l1aspm(pdev); err = pci_enable_device(pdev); if (err) return err; @@ -4058,16 +4090,15 @@ static struct pci_error_handlers e1000_err_handler = { }; static struct pci_device_id e1000_pci_tbl[] = { - /* - * Support for 82571/2/3, es2lan and ich8 will be phased in - * stepwise. - { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 }, @@ -4090,8 +4121,6 @@ static struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan }, - */ - { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 3327892..df266c3 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -262,13 +262,6 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) .max = MAX_RXDELAY } } }; - /* modify min and default if 82573 for slow ping w/a, - * a value greater than 8 needs to be set for RDTR */ - if (adapter->flags & FLAG_HAS_ASPM) { - opt.def = 32; - opt.arg.r.min = 8; - } - if (num_RxIntDelay > bd) { adapter->rx_int_delay = RxIntDelay[bd]; e1000_validate_option(&adapter->rx_int_delay, &opt, diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 7932318..fc6fee1 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -49,8 +49,7 @@ static const u16 e1000_igp_2_cable_length_table[] = 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, 124}; #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ - (sizeof(e1000_igp_2_cable_length_table) / \ - sizeof(e1000_igp_2_cable_length_table[0])) + ARRAY_SIZE(e1000_igp_2_cable_length_table) /** * e1000e_check_reset_block_generic - Check if PHY reset is blocked diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c index 70509ed..d5459a8 100644 --- a/drivers/net/eexpress.c +++ b/drivers/net/eexpress.c @@ -456,8 +456,9 @@ static int eexp_open(struct net_device *dev) if (!dev->irq || !irqrmap[dev->irq]) return -ENXIO; - ret = request_irq(dev->irq,&eexp_irq,0,dev->name,dev); - if (ret) return ret; + ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev); + if (ret) + return ret; if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) { printk(KERN_WARNING "EtherExpress io port %x, is busy.\n" @@ -768,7 +769,7 @@ static void eexp_cmd_clear(struct net_device *dev) } } -static irqreturn_t eexp_irq(int irq, void *dev_info) +static irqreturn_t eexp_irq(int dummy, void *dev_info) { struct net_device *dev = dev_info; struct net_local *lp; @@ -783,8 +784,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info) old_read_ptr = inw(ioaddr+READ_PTR); old_write_ptr = inw(ioaddr+WRITE_PTR); - outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ); - + outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ); status = scb_status(dev); @@ -851,7 +851,7 @@ static irqreturn_t eexp_irq(int irq, void *dev_info) eexp_cmd_clear(dev); - outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); + outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ); #if NET_DEBUG > 6 printk("%s: leaving eexp_irq()\n", dev->name); diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index aec9ab1..230878b 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c @@ -37,24 +37,6 @@ #include "gianfar.h" -#define GFAR_ATTR(_name) \ -static ssize_t gfar_show_##_name(struct device *dev, \ - struct device_attribute *attr, char *buf); \ -static ssize_t gfar_set_##_name(struct device *dev, \ - struct device_attribute *attr, \ - const char *buf, size_t count); \ -static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name) - -#define GFAR_CREATE_FILE(_dev, _name) \ - device_create_file(&_dev->dev, &dev_attr_##_name) - -GFAR_ATTR(bd_stash); -GFAR_ATTR(rx_stash_size); -GFAR_ATTR(rx_stash_index); -GFAR_ATTR(fifo_threshold); -GFAR_ATTR(fifo_starve); -GFAR_ATTR(fifo_starve_off); - static ssize_t gfar_show_bd_stash(struct device *dev, struct device_attribute *attr, char *buf) { @@ -100,6 +82,8 @@ static ssize_t gfar_set_bd_stash(struct device *dev, return count; } +DEVICE_ATTR(bd_stash, 0644, gfar_show_bd_stash, gfar_set_bd_stash); + static ssize_t gfar_show_rx_stash_size(struct device *dev, struct device_attribute *attr, char *buf) { @@ -146,6 +130,9 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev, return count; } +DEVICE_ATTR(rx_stash_size, 0644, gfar_show_rx_stash_size, + gfar_set_rx_stash_size); + /* Stashing will only be enabled when rx_stash_size != 0 */ static ssize_t gfar_show_rx_stash_index(struct device *dev, struct device_attribute *attr, @@ -184,6 +171,9 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev, return count; } +DEVICE_ATTR(rx_stash_index, 0644, gfar_show_rx_stash_index, + gfar_set_rx_stash_index); + static ssize_t gfar_show_fifo_threshold(struct device *dev, struct device_attribute *attr, char *buf) @@ -219,6 +209,9 @@ static ssize_t gfar_set_fifo_threshold(struct device *dev, return count; } +DEVICE_ATTR(fifo_threshold, 0644, gfar_show_fifo_threshold, + gfar_set_fifo_threshold); + static ssize_t gfar_show_fifo_starve(struct device *dev, struct device_attribute *attr, char *buf) { @@ -253,6 +246,8 @@ static ssize_t gfar_set_fifo_starve(struct device *dev, return count; } +DEVICE_ATTR(fifo_starve, 0644, gfar_show_fifo_starve, gfar_set_fifo_starve); + static ssize_t gfar_show_fifo_starve_off(struct device *dev, struct device_attribute *attr, char *buf) @@ -288,9 +283,13 @@ static ssize_t gfar_set_fifo_starve_off(struct device *dev, return count; } +DEVICE_ATTR(fifo_starve_off, 0644, gfar_show_fifo_starve_off, + gfar_set_fifo_starve_off); + void gfar_init_sysfs(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); + int rc; /* Initialize the default values */ priv->rx_stash_size = DEFAULT_STASH_LENGTH; @@ -301,11 +300,12 @@ void gfar_init_sysfs(struct net_device *dev) priv->bd_stash_en = DEFAULT_BD_STASH; /* Create our sysfs files */ - GFAR_CREATE_FILE(dev, bd_stash); - GFAR_CREATE_FILE(dev, rx_stash_size); - GFAR_CREATE_FILE(dev, rx_stash_index); - GFAR_CREATE_FILE(dev, fifo_threshold); - GFAR_CREATE_FILE(dev, fifo_starve); - GFAR_CREATE_FILE(dev, fifo_starve_off); - + rc = device_create_file(&dev->dev, &dev_attr_bd_stash); + rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_size); + rc |= device_create_file(&dev->dev, &dev_attr_rx_stash_index); + rc |= device_create_file(&dev->dev, &dev_attr_fifo_threshold); + rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve); + rc |= device_create_file(&dev->dev, &dev_attr_fifo_starve_off); + if (rc) + dev_err(&dev->dev, "Error creating gianfar sysfs files.\n"); } diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 353d13e..f905159 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -201,7 +201,6 @@ static void z8530_init(void); static void init_channel(struct scc_channel *scc); static void scc_key_trx (struct scc_channel *scc, char tx); -static irqreturn_t scc_isr(int irq, void *dev_id); static void scc_init_timer(struct scc_channel *scc); static int scc_net_alloc(const char *name, struct scc_channel *scc); @@ -629,6 +628,7 @@ static void scc_isr_dispatch(struct scc_channel *scc, int vector) static irqreturn_t scc_isr(int irq, void *dev_id) { + int chip_irq = (long) dev_id; unsigned char vector; struct scc_channel *scc; struct scc_ctrl *ctrl; @@ -665,7 +665,7 @@ static irqreturn_t scc_isr(int irq, void *dev_id) ctrl = SCC_ctrl; while (ctrl->chan_A) { - if (ctrl->irq != irq) + if (ctrl->irq != chip_irq) { ctrl++; continue; @@ -1732,7 +1732,9 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (!Ivec[hwcfg.irq].used && hwcfg.irq) { - if (request_irq(hwcfg.irq, scc_isr, IRQF_DISABLED, "AX.25 SCC", NULL)) + if (request_irq(hwcfg.irq, scc_isr, + IRQF_DISABLED, "AX.25 SCC", + (void *)(long) hwcfg.irq)) printk(KERN_WARNING "z8530drv: warning, cannot get IRQ %d\n", hwcfg.irq); else Ivec[hwcfg.irq].used = 1; diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 91d83ac..46e2c52 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -83,7 +83,7 @@ History: #include #include #include -#include +#include #include #include #include @@ -161,13 +161,13 @@ static void PrTime(void) /* deduce resources out of POS registers */ -static void getaddrs(int slot, int *base, int *memlen, int *iobase, - int *irq, ibmlana_medium * medium) +static void getaddrs(struct mca_device *mdev, int *base, int *memlen, + int *iobase, int *irq, ibmlana_medium *medium) { u_char pos0, pos1; - pos0 = mca_read_stored_pos(slot, 2); - pos1 = mca_read_stored_pos(slot, 3); + pos0 = mca_device_read_stored_pos(mdev, 2); + pos1 = mca_device_read_stored_pos(mdev, 3); *base = 0xc0000 + ((pos1 & 0xf0) << 9); *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000; @@ -704,9 +704,9 @@ static void irqtxerr_handler(struct net_device *dev) /* general interrupt entry */ -static irqreturn_t irq_handler(int irq, void *device) +static irqreturn_t irq_handler(int dummy, void *device) { - struct net_device *dev = (struct net_device *) device; + struct net_device *dev = device; u16 ival; /* in case we're not meant... */ @@ -744,6 +744,7 @@ static irqreturn_t irq_handler(int irq, void *device) /* MCA info */ +#if 0 /* info available elsewhere, but this is kept for reference */ static int ibmlana_getinfo(char *buf, int slot, void *d) { int len = 0, i; @@ -771,6 +772,7 @@ static int ibmlana_getinfo(char *buf, int slot, void *d) return len; } +#endif /* open driver. Means also initialization and start of LANCE */ @@ -890,42 +892,52 @@ static void ibmlana_set_multicast_list(struct net_device *dev) * hardware check * ------------------------------------------------------------------------ */ +static int ibmlana_irq; +static int ibmlana_io; static int startslot; /* counts through slots when probing multiple devices */ -static int ibmlana_probe(struct net_device *dev) +static short ibmlana_adapter_ids[] __initdata = { + IBM_LANA_ID, + 0x0000 +}; + +static char *ibmlana_adapter_names[] __initdata = { + "IBM LAN Adapter/A", + NULL +}; + +static int ibmlana_init_one(struct device *kdev) { - int slot, z; + struct mca_device *mdev = to_mca_device(kdev); + struct net_device *dev; + int slot = mdev->slot, z, rc; int base = 0, irq = 0, iobase = 0, memlen = 0; ibmlana_priv *priv; ibmlana_medium medium; DECLARE_MAC_BUF(mac); - /* can't work without an MCA bus ;-) */ - if (MCA_bus == 0) - return -ENODEV; + dev = alloc_etherdev(sizeof(ibmlana_priv)); + if (!dev) + return -ENOMEM; + + dev->irq = ibmlana_irq; + dev->base_addr = ibmlana_io; base = dev->mem_start; irq = dev->irq; - for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) { - /* deduce card addresses */ - getaddrs(slot, &base, &memlen, &iobase, &irq, &medium); - - /* slot already in use ? */ - if (mca_is_adapter_used(slot)) - continue; - /* were we looking for something different ? */ - if (dev->irq && dev->irq != irq) - continue; - if (dev->mem_start && dev->mem_start != base) - continue; - /* found something that matches */ - break; - } + /* deduce card addresses */ + getaddrs(mdev, &base, &memlen, &iobase, &irq, &medium); - /* nothing found ? */ - if (slot == -1) - return (base != 0 || irq != 0) ? -ENXIO : -ENODEV; + /* were we looking for something different ? */ + if (dev->irq && dev->irq != irq) { + rc = -ENODEV; + goto err_out; + } + if (dev->mem_start && dev->mem_start != base) { + rc = -ENODEV; + goto err_out; + } /* announce success */ printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1); @@ -934,16 +946,16 @@ static int ibmlana_probe(struct net_device *dev) if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) { printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase); startslot = slot + 1; - return -EBUSY; + rc = -EBUSY; + goto err_out; } priv = netdev_priv(dev); priv->slot = slot; - priv->realirq = irq; + priv->realirq = mca_device_transform_irq(mdev, irq); priv->medium = medium; spin_lock_init(&priv->lock); - /* set base + irq for this device (irq not allocated so far) */ dev->irq = 0; @@ -955,22 +967,18 @@ static int ibmlana_probe(struct net_device *dev) if (!priv->base) { printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME); startslot = slot + 1; - release_region(iobase, IBM_LANA_IORANGE); - return -EBUSY; + rc = -EBUSY; + goto err_out_reg; } - /* make procfs entries */ - mca_set_adapter_name(slot, "IBM LAN Adapter/A"); - mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev); - - mca_mark_as_used(slot); + mca_device_set_name(mdev, ibmlana_adapter_names[mdev->index]); + mca_device_set_claim(mdev, 1); /* set methods */ dev->open = ibmlana_open; dev->stop = ibmlana_close; dev->hard_start_xmit = ibmlana_tx; - dev->do_ioctl = NULL; dev->set_multicast_list = ibmlana_set_multicast_list; dev->flags |= IFF_MULTICAST; @@ -996,6 +1004,35 @@ static int ibmlana_probe(struct net_device *dev) startslot = slot + 1; + rc = register_netdev(dev); + if (rc) + goto err_out_claimed; + + dev_set_drvdata(kdev, dev); + return 0; + +err_out_claimed: + mca_device_set_claim(mdev, 0); + iounmap(priv->base); +err_out_reg: + release_region(iobase, IBM_LANA_IORANGE); +err_out: + free_netdev(dev); + return rc; +} + +static int ibmlana_remove_one(struct device *kdev) +{ + struct mca_device *mdev = to_mca_device(kdev); + struct net_device *dev = dev_get_drvdata(kdev); + ibmlana_priv *priv = netdev_priv(dev); + + unregister_netdev(dev); + /*DeinitBoard(dev); */ + release_region(dev->base_addr, IBM_LANA_IORANGE); + mca_device_set_claim(mdev, 0); + iounmap(priv->base); + free_netdev(dev); return 0; } @@ -1003,66 +1040,31 @@ static int ibmlana_probe(struct net_device *dev) * modularization support * ------------------------------------------------------------------------ */ -#ifdef MODULE - -#define DEVMAX 5 - -static struct net_device *moddevs[DEVMAX]; -static int irq; -static int io; - -module_param(irq, int, 0); -module_param(io, int, 0); +module_param_named(irq, ibmlana_irq, int, 0); +module_param_named(io, ibmlana_io, int, 0); MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number"); MODULE_PARM_DESC(io, "IBM LAN/A I/O base address"); MODULE_LICENSE("GPL"); -int init_module(void) -{ - int z; +static struct mca_driver ibmlana_driver = { + .id_table = ibmlana_adapter_ids, + .driver = { + .name = "ibmlana", + .bus = &mca_bus_type, + .probe = ibmlana_init_one, + .remove = ibmlana_remove_one, + }, +}; - startslot = 0; - for (z = 0; z < DEVMAX; z++) { - struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv)); - if (!dev) - break; - dev->irq = irq; - dev->base_addr = io; - if (ibmlana_probe(dev)) { - free_netdev(dev); - break; - } - if (register_netdev(dev)) { - ibmlana_priv *priv = netdev_priv(dev); - release_region(dev->base_addr, IBM_LANA_IORANGE); - mca_mark_as_unused(priv->slot); - mca_set_adapter_name(priv->slot, ""); - mca_set_adapter_procfn(priv->slot, NULL, NULL); - iounmap(priv->base); - free_netdev(dev); - break; - } - moddevs[z] = dev; - } - return (z > 0) ? 0 : -EIO; +static int __init ibmlana_init_module(void) +{ + return mca_register_driver(&ibmlana_driver); } -void cleanup_module(void) +static void __exit ibmlana_cleanup_module(void) { - int z; - for (z = 0; z < DEVMAX; z++) { - struct net_device *dev = moddevs[z]; - if (dev) { - ibmlana_priv *priv = netdev_priv(dev); - unregister_netdev(dev); - /*DeinitBoard(dev); */ - release_region(dev->base_addr, IBM_LANA_IORANGE); - mca_mark_as_unused(priv->slot); - mca_set_adapter_name(priv->slot, ""); - mca_set_adapter_procfn(priv->slot, NULL, NULL); - iounmap(priv->base); - free_netdev(dev); - } - } + mca_unregister_driver(&ibmlana_driver); } -#endif /* MODULE */ + +module_init(ibmlana_init_module); +module_exit(ibmlana_cleanup_module); diff --git a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h index 66fc243..39829cf 100644 --- a/drivers/net/irda/irport.h +++ b/drivers/net/irda/irport.h @@ -74,7 +74,7 @@ struct irport_cb { /* For piggyback drivers */ void *priv; void (*change_speed)(void *priv, __u32 speed); - irqreturn_t (*interrupt)(int irq, void *dev_id); + irq_handler_t interrupt; }; #endif /* IRPORT_H */ diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 7e7b582..1f26da7 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -1505,22 +1505,13 @@ static void smsc_ircc_sir_receive(struct smsc_ircc_cb *self) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t smsc_ircc_interrupt(int dummy, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - struct smsc_ircc_cb *self; + struct net_device *dev = dev_id; + struct smsc_ircc_cb *self = netdev_priv(dev); int iobase, iir, lcra, lsr; irqreturn_t ret = IRQ_NONE; - if (dev == NULL) { - printk(KERN_WARNING "%s: irq %d for unknown device.\n", - driver_name, irq); - goto irq_ret; - } - - self = netdev_priv(dev); - IRDA_ASSERT(self != NULL, return IRQ_NONE;); - /* Serialise the interrupt handler in various CPUs, stop Tx path */ spin_lock(&self->lock); @@ -1565,7 +1556,7 @@ static irqreturn_t smsc_ircc_interrupt(int irq, void *dev_id) irq_ret_unlock: spin_unlock(&self->lock); - irq_ret: + return ret; } diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index 126ec7c..58e1287 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -1346,19 +1346,13 @@ static int RxTimerHandler(struct via_ircc_cb *self, int iobase) * An interrupt from the chip has arrived. Time to do some work * */ -static irqreturn_t via_ircc_interrupt(int irq, void *dev_id) +static irqreturn_t via_ircc_interrupt(int dummy, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; - struct via_ircc_cb *self; + struct net_device *dev = dev_id; + struct via_ircc_cb *self = dev->priv; int iobase; u8 iHostIntType, iRxIntType, iTxIntType; - if (!dev) { - IRDA_WARNING("%s: irq %d for unknown device.\n", driver_name, - irq); - return IRQ_NONE; - } - self = (struct via_ircc_cb *) dev->priv; iobase = self->io.fir_base; spin_lock(&self->lock); iHostIntType = GetHostStatus(iobase); diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index bc51432..a021a6e 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -234,14 +234,10 @@ enum ixbge_state_t { }; enum ixgbe_boards { - board_82598AF, - board_82598EB, - board_82598AT, + board_82598, }; -extern struct ixgbe_info ixgbe_82598AF_info; -extern struct ixgbe_info ixgbe_82598EB_info; -extern struct ixgbe_info ixgbe_82598AT_info; +extern struct ixgbe_info ixgbe_82598_info; extern char ixgbe_driver_name[]; extern const char ixgbe_driver_version[]; diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index 4d64673..6321b05 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -50,8 +50,6 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed, bool autoneg, bool autoneg_wait_to_complete); static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw); -static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed, - bool *link_up); static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed, bool autoneg, bool autoneg_wait_to_complete); @@ -64,6 +62,28 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES; hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; + /* PHY ops are filled in by default properly for Fiber only */ + if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) { + hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598; + hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598; + hw->mac.ops.get_link_settings = + &ixgbe_get_copper_link_settings_82598; + + /* Call PHY identify routine to get the phy type */ + ixgbe_identify_phy(hw); + + switch (hw->phy.type) { + case ixgbe_phy_tn: + hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link; + hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link; + hw->phy.ops.setup_link_speed = + &ixgbe_setup_tnx_phy_link_speed; + break; + default: + break; + } + } + return 0; } @@ -206,6 +226,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) autoc_reg |= hw->mac.link_mode_select; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + IXGBE_WRITE_FLUSH(hw); msleep(50); } @@ -314,7 +335,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, * ixgbe_hw This will write the AUTOC register based on the new * stored values */ - hw->phy.ops.setup(hw); + hw->mac.ops.setup_link(hw); } return status; @@ -332,72 +353,18 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, **/ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) { - s32 status; - u32 speed = 0; - bool link_up = false; - - /* Set up MAC */ - hw->phy.ops.setup(hw); + s32 status = 0; /* Restart autonegotiation on PHY */ - status = hw->phy.ops.setup(hw); - - /* Synchronize MAC to PHY speed */ - if (status == 0) - status = hw->phy.ops.check(hw, &speed, &link_up); - - return status; -} + if (hw->phy.ops.setup_link) + status = hw->phy.ops.setup_link(hw); -/** - * ixgbe_check_copper_link_82598 - Syncs MAC & PHY link settings - * @hw: pointer to hardware structure - * @speed: pointer to link speed - * @link_up: true if link is up, false otherwise - * - * Reads the mac link, phy link, and synchronizes the MAC to PHY. - **/ -static s32 ixgbe_check_copper_link_82598(struct ixgbe_hw *hw, u32 *speed, - bool *link_up) -{ - s32 status; - u32 phy_speed = 0; - bool phy_link = false; + /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */ + hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); + hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; - /* This is the speed and link the MAC is set at */ - hw->phy.ops.check(hw, speed, link_up); - - /* - * Check current speed and link status of the PHY register. - * This is a vendor specific register and may have to - * be changed for other copper PHYs. - */ - status = hw->phy.ops.check(hw, &phy_speed, &phy_link); - - if ((status == 0) && (phy_link)) { - /* - * Check current link status of the MACs link's register - * matches that of the speed in the PHY register - */ - if (*speed != phy_speed) { - /* - * The copper PHY requires 82598 attach type to be XAUI - * for 10G and BX for 1G - */ - hw->mac.link_attach_type = - (IXGBE_AUTOC_10G_XAUI | IXGBE_AUTOC_1G_BX); - - /* Synchronize the MAC speed to the PHY speed */ - status = hw->phy.ops.setup_speed(hw, phy_speed, false, - false); - if (status == 0) - hw->phy.ops.check(hw, speed, link_up); - else - status = IXGBE_ERR_LINK_SETUP; - } - } else { - *link_up = phy_link; - } + /* Set up MAC */ + hw->mac.ops.setup_link(hw); return status; } @@ -415,16 +382,19 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed, bool autoneg, bool autoneg_wait_to_complete) { - s32 status; - bool link_up = 0; + s32 status = 0; /* Setup the PHY according to input speed */ - status = hw->phy.ops.setup_speed(hw, speed, autoneg, - autoneg_wait_to_complete); + if (hw->phy.ops.setup_link_speed) + status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, + autoneg_wait_to_complete); + + /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ + hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); + hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; - /* Synchronize MAC to PHY speed */ - if (status == 0) - status = hw->phy.ops.check(hw, &speed, &link_up); + /* Set up MAC */ + hw->mac.ops.setup_link(hw); return status; } @@ -542,47 +512,15 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) static struct ixgbe_mac_operations mac_ops_82598 = { .reset = &ixgbe_reset_hw_82598, .get_media_type = &ixgbe_get_media_type_82598, + .setup_link = &ixgbe_setup_mac_link_82598, + .check_link = &ixgbe_check_mac_link_82598, + .setup_link_speed = &ixgbe_setup_mac_link_speed_82598, + .get_link_settings = &ixgbe_get_link_settings_82598, }; -static struct ixgbe_phy_operations phy_ops_82598EB = { - .setup = &ixgbe_setup_copper_link_82598, - .check = &ixgbe_check_copper_link_82598, - .setup_speed = &ixgbe_setup_copper_link_speed_82598, - .get_settings = &ixgbe_get_copper_link_settings_82598, -}; - -struct ixgbe_info ixgbe_82598EB_info = { - .mac = ixgbe_mac_82598EB, - .get_invariants = &ixgbe_get_invariants_82598, - .mac_ops = &mac_ops_82598, - .phy_ops = &phy_ops_82598EB, -}; - -static struct ixgbe_phy_operations phy_ops_82598AT = { - .setup = &ixgbe_setup_tnx_phy_link, - .check = &ixgbe_check_tnx_phy_link, - .setup_speed = &ixgbe_setup_tnx_phy_link_speed, - .get_settings = &ixgbe_get_copper_link_settings_82598, -}; - -struct ixgbe_info ixgbe_82598AT_info = { - .mac = ixgbe_mac_82598EB, - .get_invariants = &ixgbe_get_invariants_82598, - .mac_ops = &mac_ops_82598, - .phy_ops = &phy_ops_82598AT, -}; - -static struct ixgbe_phy_operations phy_ops_82598AF = { - .setup = &ixgbe_setup_mac_link_82598, - .check = &ixgbe_check_mac_link_82598, - .setup_speed = &ixgbe_setup_mac_link_speed_82598, - .get_settings = &ixgbe_get_link_settings_82598, -}; - -struct ixgbe_info ixgbe_82598AF_info = { +struct ixgbe_info ixgbe_82598_info = { .mac = ixgbe_mac_82598EB, .get_invariants = &ixgbe_get_invariants_82598, .mac_ops = &mac_ops_82598, - .phy_ops = &phy_ops_82598AF, }; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 512e3b2..7fd6aeb 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -74,7 +74,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw) ixgbe_clear_vfta(hw); /* Set up link */ - hw->phy.ops.setup(hw); + hw->mac.ops.setup_link(hw); /* Clear statistics registers */ ixgbe_clear_hw_cntrs(hw); @@ -83,6 +83,7 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw) ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_NS_DIS; IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); + IXGBE_WRITE_FLUSH(hw); /* Clear adapter stopped flag */ hw->adapter_stopped = false; @@ -297,6 +298,7 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index) led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); return 0; } @@ -314,6 +316,7 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index) led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); return 0; } @@ -496,6 +499,7 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) /* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */ swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI); IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm); + IXGBE_WRITE_FLUSH(hw); } /** @@ -950,7 +954,7 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) u32 rmcs_reg; if (packetbuf_num < 0 || packetbuf_num > 7) - hw_dbg(hw, "Invalid packet buffer number [%d], expected range" + hw_dbg(hw, "Invalid packet buffer number [%d], expected range " "is 0-7\n", packetbuf_num); frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); @@ -1132,7 +1136,7 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) } /** - * ixgbe_read_analog_reg8- Reads 8 bit 82598 Atlas analog register + * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register * @hw: pointer to hardware structure * @reg: analog register to read * @val: read value @@ -1154,7 +1158,7 @@ s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val) } /** - * ixgbe_write_analog_reg8- Writes 8 bit Atlas analog register + * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register * @hw: pointer to hardware structure * @reg: atlas register to write * @val: value to write diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index a4e576a..3635344 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -96,8 +96,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \ ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \ (sizeof(struct ixgbe_queue_stats) / sizeof(u64))) -#define IXGBE_GLOBAL_STATS_LEN \ - sizeof(ixgbe_gstrings_stats) / sizeof(struct ixgbe_stats) +#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) static int ixgbe_get_settings(struct net_device *netdev, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 00bc525..bad0160 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -54,9 +54,7 @@ static const char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { - [board_82598AF] = &ixgbe_82598AF_info, - [board_82598EB] = &ixgbe_82598EB_info, - [board_82598AT] = &ixgbe_82598AT_info, + [board_82598] = &ixgbe_82598_info, }; /* ixgbe_pci_tbl - PCI Device ID Table @@ -69,13 +67,13 @@ static const struct ixgbe_info *ixgbe_info_tbl[] = { */ static struct pci_device_id ixgbe_pci_tbl[] = { {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT), - board_82598AF }, + board_82598 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), - board_82598AF }, + board_82598 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT_DUAL_PORT), - board_82598AT }, + board_82598 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), - board_82598EB }, + board_82598 }, /* required last entry */ {0, } @@ -734,7 +732,7 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter, u32 *num_rx_queues) { struct net_device *netdev = adapter->netdev; int flags, err; - irqreturn_t(*handler) (int, void *) = &ixgbe_intr; + irq_handler_t handler = ixgbe_intr; flags = IRQF_SHARED; @@ -1571,8 +1569,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) dev_err(&pdev->dev, "HW Init failed\n"); return -EIO; } - if (hw->phy.ops.setup_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true, - false)) { + if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true, + false)) { dev_err(&pdev->dev, "Link Speed setup failed\n"); return -EIO; } @@ -2039,7 +2037,7 @@ static void ixgbe_watchdog(unsigned long data) bool link_up; u32 link_speed = 0; - adapter->hw.phy.ops.check(&adapter->hw, &(link_speed), &link_up); + adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); if (link_up) { if (!netif_carrier_ok(netdev)) { @@ -2607,7 +2605,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* Setup hw api */ memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops)); - memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); err = ii->get_invariants(hw); if (err) diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index 199e8f6..aa3ea72 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -31,7 +31,6 @@ #include "ixgbe_type.h" -s32 ixgbe_init_shared_code_phy(struct ixgbe_hw *hw); s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw); s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up); s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg, diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index fdcde16..e60787a 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1244,13 +1244,16 @@ struct ixgbe_hw; struct ixgbe_mac_operations { s32 (*reset)(struct ixgbe_hw *); enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); + s32 (*setup_link)(struct ixgbe_hw *); + s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *); + s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); + s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *); }; struct ixgbe_phy_operations { - s32 (*setup)(struct ixgbe_hw *); - s32 (*check)(struct ixgbe_hw *, u32 *, bool *); - s32 (*setup_speed)(struct ixgbe_hw *, u32, bool, bool); - s32 (*get_settings)(struct ixgbe_hw *, u32 *, bool *); + s32 (*setup_link)(struct ixgbe_hw *); + s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *); + s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); }; struct ixgbe_mac_info { @@ -1267,7 +1270,6 @@ struct ixgbe_mac_info { bool link_settings_loaded; }; - struct ixgbe_eeprom_info { enum ixgbe_eeprom_type type; u16 word_size; @@ -1290,7 +1292,6 @@ struct ixgbe_info { enum ixgbe_mac_type mac; s32 (*get_invariants)(struct ixgbe_hw *); struct ixgbe_mac_operations *mac_ops; - struct ixgbe_phy_operations *phy_ops; }; struct ixgbe_hw { diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index c5095ec..591a7e4 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -1144,14 +1144,13 @@ i596_handle_CU_completion(struct net_device *dev, } static irqreturn_t -i596_interrupt (int irq, void *dev_instance) { - struct net_device *dev = (struct net_device *) dev_instance; - struct i596_private *lp; +i596_interrupt(int irq, void *dev_instance) +{ + struct net_device *dev = dev_instance; + struct i596_private *lp = dev->priv; unsigned short status, ack_cmd = 0; int frames_in = 0; - lp = (struct i596_private *) dev->priv; - /* * The 82596 examines the command, performs the required action, * and then clears the SCB command word. diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 8def865..2311143 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1431,7 +1431,7 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { }; #define MYRI10GE_NET_STATS_LEN 21 -#define MYRI10GE_STATS_LEN sizeof(myri10ge_gstrings_stats) / ETH_GSTRING_LEN +#define MYRI10GE_STATS_LEN ARRAY_SIZE(myri10ge_gstrings_stats) static void myri10ge_get_strings(struct net_device *netdev, u32 stringset, u8 * data) diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index fbc2553..e23fb67 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -113,8 +113,8 @@ #define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq) extern struct workqueue_struct *netxen_workq; -/* - * normalize a 64MB crb address to 32MB PCI window +/* + * normalize a 64MB crb address to 32MB PCI window * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 */ #define NETXEN_CRB_NORMAL(reg) \ @@ -733,11 +733,11 @@ struct netxen_skb_frag { (config_word) &= ~__tmask; \ (config_word) |= (((__tvalue) << (start)) & __tmask); \ } - + #define _netxen_clear_bits(config_word, start, bits) {\ unsigned long long __tmask = (((1ULL << (bits)) - 1) << (start)); \ (config_word) &= ~__tmask; \ -} +} /* Following defines are for the state of the buffers */ #define NETXEN_BUFFER_FREE 0 @@ -876,7 +876,7 @@ struct netxen_dummy_dma { struct netxen_adapter { struct netxen_hardware_context ahw; - + struct netxen_adapter *master; struct net_device *netdev; struct pci_dev *pdev; @@ -913,7 +913,7 @@ struct netxen_adapter { u32 temp; struct netxen_adapter_stats stats; - + u16 portno; u16 link_speed; u16 link_duplex; @@ -1015,14 +1015,8 @@ int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter); int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter); int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter); int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter); -int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter); -int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter); void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter); void netxen_nic_gbe_handle_phy_intr(struct netxen_adapter *adapter); -void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, int port, - long enable); -void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, int port, - long enable); int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, __u32 * readval); int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, @@ -1045,7 +1039,6 @@ int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, int len); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); -int netxen_nic_erase_pxe(struct netxen_adapter *adapter); /* Functions from netxen_nic_init.c */ void netxen_free_adapter_offload(struct netxen_adapter *adapter); @@ -1054,9 +1047,9 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); int netxen_load_firmware(struct netxen_adapter *adapter); int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); -int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, +int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, u8 *bytes, size_t size); -int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, +int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, u8 *bytes, size_t size); int netxen_flash_unlock(struct netxen_adapter *adapter); int netxen_backup_crbinit(struct netxen_adapter *adapter); @@ -1064,15 +1057,10 @@ int netxen_flash_erase_secondary(struct netxen_adapter *adapter); int netxen_flash_erase_primary(struct netxen_adapter *adapter); void netxen_halt_pegs(struct netxen_adapter *adapter); -int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data); int netxen_rom_se(struct netxen_adapter *adapter, int addr); -int netxen_do_rom_se(struct netxen_adapter *adapter, int addr); /* Functions from netxen_nic_isr.c */ int netxen_nic_link_ok(struct netxen_adapter *adapter); -void netxen_nic_isr_other(struct netxen_adapter *adapter); -void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link); -void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable); void netxen_initialize_adapter_sw(struct netxen_adapter *adapter); void netxen_initialize_adapter_hw(struct netxen_adapter *adapter); void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr, @@ -1089,8 +1077,6 @@ int netxen_nic_tx_has_work(struct netxen_adapter *adapter); void netxen_watchdog_task(struct work_struct *work); void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid); -void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx, - u32 ringid); int netxen_process_cmd_ring(unsigned long data); u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max); void netxen_nic_set_multi(struct net_device *netdev); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index cfb847b..7a876f4 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -86,7 +86,7 @@ static const char netxen_nic_gstrings_test[][ETH_GSTRING_LEN] = { "Link_Test_on_offline" }; -#define NETXEN_NIC_TEST_LEN sizeof(netxen_nic_gstrings_test) / ETH_GSTRING_LEN +#define NETXEN_NIC_TEST_LEN ARRAY_SIZE(netxen_nic_gstrings_test) #define NETXEN_NIC_REGS_COUNT 42 #define NETXEN_NIC_REGS_LEN (NETXEN_NIC_REGS_COUNT * sizeof(__le32)) @@ -423,11 +423,11 @@ netxen_nic_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if (eeprom->len == 0) return -EINVAL; - eeprom->magic = (adapter->pdev)->vendor | + eeprom->magic = (adapter->pdev)->vendor | ((adapter->pdev)->device << 16); offset = eeprom->offset; - ret = netxen_rom_fast_read_words(adapter, offset, bytes, + ret = netxen_rom_fast_read_words(adapter, offset, bytes, eeprom->len); if (ret < 0) return ret; @@ -453,16 +453,16 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, netxen_nic_driver_name); return ret; } - printk(KERN_INFO "%s: flash unlocked. \n", + printk(KERN_INFO "%s: flash unlocked. \n", netxen_nic_driver_name); last_schedule_time = jiffies; ret = netxen_flash_erase_secondary(adapter); if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: Flash erase failed.\n", + printk(KERN_ERR "%s: Flash erase failed.\n", netxen_nic_driver_name); return ret; } - printk(KERN_INFO "%s: secondary flash erased successfully.\n", + printk(KERN_INFO "%s: secondary flash erased successfully.\n", netxen_nic_driver_name); flash_start = 1; return 0; @@ -471,7 +471,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if (offset == NETXEN_BOOTLD_START) { ret = netxen_flash_erase_primary(adapter); if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: Flash erase failed.\n", + printk(KERN_ERR "%s: Flash erase failed.\n", netxen_nic_driver_name); return ret; } @@ -483,16 +483,16 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, if (ret != FLASH_SUCCESS) return ret; - printk(KERN_INFO "%s: primary flash erased successfully\n", + printk(KERN_INFO "%s: primary flash erased successfully\n", netxen_nic_driver_name); ret = netxen_backup_crbinit(adapter); if (ret != FLASH_SUCCESS) { - printk(KERN_ERR "%s: CRBinit backup failed.\n", + printk(KERN_ERR "%s: CRBinit backup failed.\n", netxen_nic_driver_name); return ret; } - printk(KERN_INFO "%s: CRBinit backup done.\n", + printk(KERN_INFO "%s: CRBinit backup done.\n", netxen_nic_driver_name); ready_to_flash = 1; } @@ -570,7 +570,7 @@ netxen_nic_get_pauseparam(struct net_device *dev, else pause->tx_pause = !(netxen_xg_get_xg1_mask(val)); } else { - printk(KERN_ERR"%s: Unknown board type: %x\n", + printk(KERN_ERR"%s: Unknown board type: %x\n", netxen_nic_driver_name, adapter->ahw.board_type); } } @@ -589,7 +589,7 @@ netxen_nic_set_pauseparam(struct net_device *dev, /* set flow control */ netxen_nic_read_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), &val); - + if (pause->rx_pause) netxen_gb_rx_flowctl(val); else @@ -642,10 +642,10 @@ netxen_nic_set_pauseparam(struct net_device *dev, else netxen_xg_set_xg1_mask(val); } - netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); + netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val); } else { printk(KERN_ERR "%s: Unknown board type: %x\n", - netxen_nic_driver_name, + netxen_nic_driver_name, adapter->ahw.board_type); } return 0; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 2c19b8d..a88c51f 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -33,7 +33,6 @@ #include "netxen_nic.h" #include "netxen_nic_hw.h" -#define DEFINE_GLOBAL_RECV_CRB #include "netxen_nic_phan_reg.h" @@ -161,7 +160,7 @@ struct netxen_recv_crb recv_crb_registers[] = { }, /* Jumbo frames */ { - /* crb_rcv_producer_offset: */ + /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x1f8), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x1fc), @@ -210,7 +209,7 @@ struct netxen_recv_crb recv_crb_registers[] = { }, /* Jumbo frames */ { - /* crb_rcv_producer_offset: */ + /* crb_rcv_producer_offset: */ NETXEN_NIC_REG(0x23c), /* crb_rcv_consumer_offset: */ NETXEN_NIC_REG(0x240), @@ -244,12 +243,15 @@ struct netxen_recv_crb recv_crb_registers[] = { }, }; -u64 ctx_addr_sig_regs[][3] = { +static u64 ctx_addr_sig_regs[][3] = { {NETXEN_NIC_REG(0x188), NETXEN_NIC_REG(0x18c), NETXEN_NIC_REG(0x1c0)}, {NETXEN_NIC_REG(0x190), NETXEN_NIC_REG(0x194), NETXEN_NIC_REG(0x1c4)}, {NETXEN_NIC_REG(0x198), NETXEN_NIC_REG(0x19c), NETXEN_NIC_REG(0x1c8)}, {NETXEN_NIC_REG(0x1a0), NETXEN_NIC_REG(0x1a4), NETXEN_NIC_REG(0x1cc)} }; +#define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) +#define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) +#define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) /* PCI Windowing for DDR regions. */ @@ -279,8 +281,8 @@ u64 ctx_addr_sig_regs[][3] = { #define NETXEN_NIC_WINDOW_MARGIN 0x100000 -unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, - unsigned long long addr); +static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, + unsigned long long addr); void netxen_free_hw_resources(struct netxen_adapter *adapter); int netxen_nic_set_mac(struct net_device *netdev, void *p) @@ -664,7 +666,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW_F3)); break; default: - printk(KERN_INFO "Changing the window for PCI function" + printk(KERN_INFO "Changing the window for PCI function " "%d\n", adapter->ahw.pci_func); offset = PCI_OFFSET_SECOND_RANGE(adapter, NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW)); @@ -886,11 +888,10 @@ void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value) netxen_nic_pci_change_crbwindow(adapter, 1); } -int netxen_pci_set_window_warning_count = 0; +static int netxen_pci_set_window_warning_count; -unsigned long -netxen_nic_pci_set_window(struct netxen_adapter *adapter, - unsigned long long addr) +static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, + unsigned long long addr) { static int ddr_mn_window = -1; static int qdr_sn_window = -1; @@ -952,16 +953,18 @@ netxen_nic_pci_set_window(struct netxen_adapter *adapter, return addr; } +#if 0 int netxen_nic_erase_pxe(struct netxen_adapter *adapter) { if (netxen_rom_fast_write(adapter, NETXEN_PXE_START, 0) == -1) { - printk(KERN_ERR "%s: erase pxe failed\n", + printk(KERN_ERR "%s: erase pxe failed\n", netxen_nic_driver_name); return -1; } return 0; } +#endif /* 0 */ int netxen_nic_get_board_info(struct netxen_adapter *adapter) { @@ -1036,9 +1039,9 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; if (physical_port[adapter->portnum] == 0) - netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, + netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); - else + else netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); return 0; diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h index 245bf13..a3ea1dd 100644 --- a/drivers/net/netxen/netxen_nic_hw.h +++ b/drivers/net/netxen/netxen_nic_hw.h @@ -235,7 +235,7 @@ typedef enum { ((config_word) |= 1 << 0) #define netxen_xg_set_xg1_mask(config_word) \ ((config_word) |= 1 << 3) - + #define netxen_xg_get_xg0_mask(config_word) \ _netxen_crb_get_bit((config_word), 0) #define netxen_xg_get_xg1_mask(config_word) \ @@ -273,7 +273,7 @@ typedef enum { _netxen_crb_get_bit((config_word), 4) #define netxen_gb_get_gb3_mask(config_word) \ _netxen_crb_get_bit((config_word), 6) - + #define netxen_gb_unset_gb0_mask(config_word) \ ((config_word) &= ~(1 << 0)) #define netxen_gb_unset_gb1_mask(config_word) \ @@ -437,7 +437,7 @@ typedef enum { /* * NIU GB Drop CRC Register - * + * * Bit 0 : drop_gb0 => 1:drop pkts with bad CRCs, 0:pass them on * Bit 1 : drop_gb1 => 1:drop pkts with bad CRCs, 0:pass them on * Bit 2 : drop_gb2 => 1:drop pkts with bad CRCs, 0:pass them on @@ -480,7 +480,7 @@ typedef enum { /* * MAC Control Register - * + * * Bit 0-1 : id_pool0 * Bit 2 : enable_xtnd0 * Bit 4-5 : id_pool1 @@ -515,20 +515,16 @@ typedef enum { ((config) |= (((val) & 0x0f) << 28)) /* Set promiscuous mode for a GbE interface */ -int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, +int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode); int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode); -/* get/set the MAC address for a given MAC */ -int netxen_niu_macaddr_get(struct netxen_adapter *adapter, - netxen_ethernet_macaddr_t * addr); +/* set the MAC address for a given MAC */ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t addr); -/* XG versons */ -int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, - netxen_ethernet_macaddr_t * addr); +/* XG version */ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t addr); diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 3758926..e8a0c03 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -54,13 +54,17 @@ static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; #define NETXEN_NIC_XDMA_RESET 0x8000ff -static inline void -netxen_nic_locked_write_reg(struct netxen_adapter *adapter, - unsigned long off, int *data) +static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, + uint32_t ctx, uint32_t ringid); + +#if 0 +static void netxen_nic_locked_write_reg(struct netxen_adapter *adapter, + unsigned long off, int *data) { void __iomem *addr = pci_base_offset(adapter, off); writel(*data, addr); } +#endif /* 0 */ static void crb_addr_transform_setup(void) { @@ -255,7 +259,7 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter) * netxen_decode_crb_addr(0 - utility to translate from internal Phantom CRB * address to external PCI CRB address. */ -u32 netxen_decode_crb_addr(u32 addr) +static u32 netxen_decode_crb_addr(u32 addr) { int i; u32 base_addr, offset, pci_base; @@ -282,7 +286,7 @@ static long rom_max_timeout = 100; static long rom_lock_timeout = 10000; static long rom_write_timeout = 700; -static inline int rom_lock(struct netxen_adapter *adapter) +static int rom_lock(struct netxen_adapter *adapter) { int iter; u32 done = 0; @@ -312,7 +316,7 @@ static inline int rom_lock(struct netxen_adapter *adapter) return 0; } -int netxen_wait_rom_done(struct netxen_adapter *adapter) +static int netxen_wait_rom_done(struct netxen_adapter *adapter) { long timeout = 0; long done = 0; @@ -329,7 +333,7 @@ int netxen_wait_rom_done(struct netxen_adapter *adapter) return 0; } -static inline int netxen_rom_wren(struct netxen_adapter *adapter) +static int netxen_rom_wren(struct netxen_adapter *adapter) { /* Set write enable latch in ROM status register */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); @@ -341,15 +345,15 @@ static inline int netxen_rom_wren(struct netxen_adapter *adapter) return 0; } -static inline unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter, - unsigned int addr) +static unsigned int netxen_rdcrbreg(struct netxen_adapter *adapter, + unsigned int addr) { unsigned int data = 0xdeaddead; data = netxen_nic_reg_read(adapter, addr); return data; } -static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter) +static int netxen_do_rom_rdsr(struct netxen_adapter *adapter) { netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_RDSR); @@ -359,7 +363,7 @@ static inline int netxen_do_rom_rdsr(struct netxen_adapter *adapter) return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA); } -static inline void netxen_rom_unlock(struct netxen_adapter *adapter) +static void netxen_rom_unlock(struct netxen_adapter *adapter) { u32 val; @@ -368,7 +372,7 @@ static inline void netxen_rom_unlock(struct netxen_adapter *adapter) } -int netxen_rom_wip_poll(struct netxen_adapter *adapter) +static int netxen_rom_wip_poll(struct netxen_adapter *adapter) { long timeout = 0; long wip = 1; @@ -385,8 +389,8 @@ int netxen_rom_wip_poll(struct netxen_adapter *adapter) return 0; } -static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, - int data) +static int do_rom_fast_write(struct netxen_adapter *adapter, int addr, + int data) { if (netxen_rom_wren(adapter)) { return -1; @@ -404,8 +408,8 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, return netxen_rom_wip_poll(adapter); } -static inline int -do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) +static int do_rom_fast_read(struct netxen_adapter *adapter, + int addr, int *valp) { cond_resched(); @@ -427,9 +431,8 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) return 0; } -static inline int -do_rom_fast_read_words(struct netxen_adapter *adapter, int addr, - u8 *bytes, size_t size) +static int do_rom_fast_read_words(struct netxen_adapter *adapter, int addr, + u8 *bytes, size_t size) { int addridx; int ret = 0; @@ -446,7 +449,7 @@ do_rom_fast_read_words(struct netxen_adapter *adapter, int addr, } int -netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, +netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, u8 *bytes, size_t size) { int ret; @@ -473,6 +476,7 @@ int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) return ret; } +#if 0 int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) { int ret = 0; @@ -484,9 +488,10 @@ int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data) netxen_rom_unlock(adapter); return ret; } +#endif /* 0 */ -static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, - int addr, u8 *bytes, size_t size) +static int do_rom_fast_write_words(struct netxen_adapter *adapter, + int addr, u8 *bytes, size_t size) { int addridx = addr; int ret = 0; @@ -500,7 +505,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, ret = do_rom_fast_write(adapter, addridx, data); if (ret < 0) return ret; - + while(1) { int data1; @@ -513,7 +518,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, if (timeout++ >= rom_write_timeout) { if (last_attempt++ < 4) { - ret = do_rom_fast_write(adapter, + ret = do_rom_fast_write(adapter, addridx, data); if (ret < 0) return ret; @@ -533,7 +538,7 @@ static inline int do_rom_fast_write_words(struct netxen_adapter *adapter, return ret; } -int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, +int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, u8 *bytes, size_t size) { int ret = 0; @@ -548,7 +553,7 @@ int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, return ret; } -int netxen_rom_wrsr(struct netxen_adapter *adapter, int data) +static int netxen_rom_wrsr(struct netxen_adapter *adapter, int data) { int ret; @@ -557,7 +562,7 @@ int netxen_rom_wrsr(struct netxen_adapter *adapter, int data) return ret; netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data); - netxen_crb_writelit_adapter(adapter, + netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1); ret = netxen_wait_rom_done(adapter); @@ -567,7 +572,7 @@ int netxen_rom_wrsr(struct netxen_adapter *adapter, int data) return netxen_rom_wip_poll(adapter); } -int netxen_rom_rdsr(struct netxen_adapter *adapter) +static int netxen_rom_rdsr(struct netxen_adapter *adapter) { int ret; @@ -587,7 +592,7 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter) char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL); if (!buffer) - return -ENOMEM; + return -ENOMEM; /* unlock sector 63 */ val = netxen_rom_rdsr(adapter); val = val & 0xe3; @@ -600,12 +605,12 @@ int netxen_backup_crbinit(struct netxen_adapter *adapter) goto out_kfree; /* copy sector 0 to sector 63 */ - ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START, + ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START, buffer, NETXEN_FLASH_SECTOR_SIZE); if (ret != FLASH_SUCCESS) goto out_kfree; - ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START, + ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START, buffer, NETXEN_FLASH_SECTOR_SIZE); if (ret != FLASH_SUCCESS) goto out_kfree; @@ -632,7 +637,7 @@ out_kfree: return ret; } -int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) +static int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) { netxen_rom_wren(adapter); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); @@ -646,16 +651,16 @@ int netxen_do_rom_se(struct netxen_adapter *adapter, int addr) return netxen_rom_wip_poll(adapter); } -void check_erased_flash(struct netxen_adapter *adapter, int addr) +static void check_erased_flash(struct netxen_adapter *adapter, int addr) { int i; int val; int count = 0, erased_errors = 0; int range; - range = (addr == NETXEN_USER_START) ? + range = (addr == NETXEN_USER_START) ? NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE; - + for (i = addr; i < range; i += 4) { netxen_rom_fast_read(adapter, i, &val); if (val != 0xffffffff) @@ -682,8 +687,8 @@ int netxen_rom_se(struct netxen_adapter *adapter, int addr) return ret; } -int -netxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end) +static int netxen_flash_erase_sections(struct netxen_adapter *adapter, + int start, int end) { int ret = FLASH_SUCCESS; int i; @@ -990,7 +995,7 @@ int netxen_nic_rx_has_work(struct netxen_adapter *adapter) return 0; } -static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) +static int netxen_nic_check_temp(struct netxen_adapter *adapter) { struct net_device *netdev = adapter->netdev; uint32_t temp, temp_state, temp_val; @@ -1064,9 +1069,8 @@ void netxen_watchdog_task(struct work_struct *work) * and if the number of receives exceeds RX_BUFFERS_REFILL, then we * invoke the routine to send more rx buffers to the Phantom... */ -void -netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, - struct status_desc *desc) +static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, + struct status_desc *desc) { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; @@ -1102,8 +1106,8 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, } if (buffer->lro_current_frags != buffer->lro_expected_frags) { if (buffer->lro_expected_frags != 0) { - printk("LRO: (refhandle:%x) recv frag." - "wait for last. flags: %x expected:%d" + printk("LRO: (refhandle:%x) recv frag. " + "wait for last. flags: %x expected:%d " "have:%d\n", index, netxen_get_sts_desc_lro_last_frag(desc), buffer->lro_expected_frags, @@ -1460,8 +1464,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) } } -void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, - uint32_t ringid) +static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, + uint32_t ctx, uint32_t ringid) { struct pci_dev *pdev = adapter->ahw.pdev; struct sk_buff *skb; @@ -1493,7 +1497,7 @@ void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, uint32_t ctx, count++; /* now there should be no failure */ pdesc = &rcv_desc->desc_head[producer]; skb_reserve(skb, 2); - /* + /* * This will be setup when we receive the * buffer after it has been filled * skb->dev = netdev; diff --git a/drivers/net/netxen/netxen_nic_isr.c b/drivers/net/netxen/netxen_nic_isr.c index b2de6b6..48a404a 100644 --- a/drivers/net/netxen/netxen_nic_isr.c +++ b/drivers/net/netxen/netxen_nic_isr.c @@ -48,7 +48,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) /* total packets received */ stats->rx_packets = adapter->stats.no_rcv; /* total packets transmitted */ - stats->tx_packets = adapter->stats.xmitedframes + + stats->tx_packets = adapter->stats.xmitedframes + adapter->stats.xmitfinished; /* total bytes received */ stats->rx_bytes = adapter->stats.rxbytes; @@ -66,7 +66,8 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) return stats; } -void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link) +static void netxen_indicate_link_status(struct netxen_adapter *adapter, + u32 link) { struct net_device *netdev = adapter->netdev; @@ -76,13 +77,14 @@ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 link) netif_carrier_off(netdev); } +#if 0 void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) { __u32 int_src; /* This should clear the interrupt source */ if (adapter->phy_read) - adapter->phy_read(adapter, + adapter->phy_read(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, &int_src); if (int_src == 0) { @@ -111,7 +113,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) DPRINTK(INFO, "SPEED CHANGED OR LINK STATUS CHANGED \n"); if (adapter->phy_read - && adapter->phy_read(adapter, + && adapter->phy_read(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status) == 0) { if (netxen_get_phy_int_link_status_changed(int_src)) { @@ -125,7 +127,7 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) netxen_nic_driver_name, adapter->netdev->name); } - netxen_indicate_link_status(adapter, + netxen_indicate_link_status(adapter, netxen_get_phy_link (status)); } @@ -134,8 +136,9 @@ void netxen_handle_port_int(struct netxen_adapter *adapter, u32 enable) if (adapter->enable_phy_interrupts) adapter->enable_phy_interrupts(adapter); } +#endif /* 0 */ -void netxen_nic_isr_other(struct netxen_adapter *adapter) +static void netxen_nic_isr_other(struct netxen_adapter *adapter) { int portno = adapter->portnum; u32 val, linkup, qg_linksup; diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a80f0cd..3dd3af2 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -89,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); struct workqueue_struct *netxen_workq; static void netxen_watchdog(unsigned long); -static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, - uint32_t crb_producer) +static void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, + uint32_t crb_producer) { switch (adapter->portnum) { case 0: @@ -118,8 +118,8 @@ static inline void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter } } -static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, - u32 crb_consumer) +static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter, + u32 crb_consumer) { switch (adapter->portnum) { case 0: @@ -148,7 +148,6 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter } #define ADAPTER_LIST_SIZE 12 -int netxen_cards_found; static void netxen_nic_disable_int(struct netxen_adapter *adapter) { @@ -287,7 +286,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_INFO "%s \n", netxen_nic_driver_string); if (pdev->class != 0x020000) { - printk(KERN_ERR"NetXen function %d, class %x will not" + printk(KERN_ERR"NetXen function %d, class %x will not " "be enabled.\n",pci_func_id, pdev->class); return -ENODEV; } @@ -351,7 +350,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) first_page_group_start = 0; first_page_group_end = 0; } else { - err = -EIO; + err = -EIO; goto err_out_free_netdev; } @@ -411,7 +410,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev->open = netxen_nic_open; netdev->stop = netxen_nic_close; netdev->hard_start_xmit = netxen_nic_xmit_frame; - netdev->get_stats = netxen_nic_get_stats; + netdev->get_stats = netxen_nic_get_stats; netdev->set_multicast_list = netxen_nic_set_multi; netdev->set_mac_address = netxen_nic_set_mac; netdev->change_mtu = netxen_nic_change_mtu; @@ -458,8 +457,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || - (adapter->ahw.boardcfg.board_type == - NETXEN_BRDTYPE_P2_SB31_2G)) + (adapter->ahw.boardcfg.board_type == + NETXEN_BRDTYPE_P2_SB31_2G)) adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; else adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; @@ -511,7 +510,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) vmalloc(RCV_BUFFSIZE); if (rcv_desc->rx_buf_arr == NULL) { - printk(KERN_ERR "%s: Could not allocate" + printk(KERN_ERR "%s: Could not allocate " "rcv_desc->rx_buf_arr memory:%d\n", netxen_nic_driver_name, (int)RCV_BUFFSIZE); @@ -584,9 +583,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (adapter->portnum == 0) { err = netxen_initialize_adapter_offload(adapter); - if (err) + if (err) goto err_out_free_rx_buffer; - val = readl(NETXEN_CRB_NORMALIZE(adapter, + val = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); if (val == 0x55555555) { /* This is the first boot after power up */ @@ -620,7 +619,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* * Tell the hardware our version number. */ - i = (_NETXEN_NIC_LINUX_MAJOR << 16) + i = (_NETXEN_NIC_LINUX_MAJOR << 16) | ((_NETXEN_NIC_LINUX_MINOR << 8)) | (_NETXEN_NIC_LINUX_SUBVERSION); writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION)); @@ -660,7 +659,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; case NETXEN_NIC_XGBE: - printk(KERN_INFO "%s: XGbE board initialized\n", + printk(KERN_INFO "%s: XGbE board initialized\n", netxen_nic_driver_name); break; } @@ -933,7 +932,7 @@ static int netxen_nic_close(struct net_device *netdev) buffrag++; if (buffrag->dma) { pci_unmap_page(adapter->pdev, buffrag->dma, - buffrag->length, + buffrag->length, PCI_DMA_TODEVICE); buffrag->dma = 0ULL; } @@ -983,7 +982,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) } if (frag_count > MAX_BUFFERS_PER_CMD) { - printk("%s: %s netxen_nic_xmit_frame: frag_count (%d)" + printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) " "too large, can handle only %d frags\n", netxen_nic_driver_name, netdev->name, frag_count, MAX_BUFFERS_PER_CMD); @@ -1215,7 +1214,7 @@ static void netxen_tx_timeout(struct net_device *netdev) static void netxen_tx_timeout_task(struct work_struct *work) { - struct netxen_adapter *adapter = + struct netxen_adapter *adapter = container_of(work, struct netxen_adapter, tx_timeout_task); printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c index 5b9e1b3..1a4497a 100644 --- a/drivers/net/netxen/netxen_nic_niu.c +++ b/drivers/net/netxen/netxen_nic_niu.c @@ -40,7 +40,7 @@ static long phy_lock_timeout = 100000000; -static inline int phy_lock(struct netxen_adapter *adapter) +static int phy_lock(struct netxen_adapter *adapter) { int i; int done = 0, timeout = 0; @@ -68,14 +68,14 @@ static inline int phy_lock(struct netxen_adapter *adapter) return 0; } -static inline int phy_unlock(struct netxen_adapter *adapter) +static int phy_unlock(struct netxen_adapter *adapter) { readl(pci_base_offset(adapter, NETXEN_PCIE_REG(PCIE_SEM3_UNLOCK))); return 0; } -/* +/* * netxen_niu_gbe_phy_read - read a register from the GbE PHY via * mii management interface. * @@ -88,7 +88,7 @@ static inline int phy_unlock(struct netxen_adapter *adapter) * -1 on error * */ -int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, +int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, __u32 * readval) { long timeout = 0; @@ -171,7 +171,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, return result; } -/* +/* * netxen_niu_gbe_phy_write - write a register to the GbE PHY via * mii management interface. * @@ -184,7 +184,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg, * -1 on error * */ -int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, +int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg, __u32 val) { long timeout = 0; @@ -275,7 +275,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter) netxen_set_phy_int_speed_changed(enable); if (0 != - netxen_niu_gbe_phy_write(adapter, + netxen_niu_gbe_phy_write(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE, enable)) result = -EIO; @@ -300,17 +300,19 @@ int netxen_niu_gbe_disable_phy_interrupts(struct netxen_adapter *adapter) return result; } +#if 0 int netxen_niu_xgbe_clear_phy_interrupts(struct netxen_adapter *adapter) { netxen_crb_writelit_adapter(adapter, NETXEN_NIU_ACTIVE_INT, -1); return 0; } +#endif /* 0 */ -int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) +static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) { int result = 0; if (0 != - netxen_niu_gbe_phy_write(adapter, + netxen_niu_gbe_phy_write(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, -EIO)) result = -EIO; @@ -318,12 +320,12 @@ int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter) return result; } -/* +/* * netxen_niu_gbe_set_mii_mode- Set 10/100 Mbit Mode for GbE MAC * */ -void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, - int port, long enable) +static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, + int port, long enable) { netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), @@ -342,9 +344,9 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); if (enable) { - /* - * Do NOT enable flow control until a suitable solution for - * shutting down pause frames is found. + /* + * Do NOT enable flow control until a suitable solution for + * shutting down pause frames is found. */ netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), @@ -357,11 +359,11 @@ void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter, printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n"); } -/* +/* * netxen_niu_gbe_set_gmii_mode- Set GbE Mode for GbE MAC */ -void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, - int port, long enable) +static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, + int port, long enable) { netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), @@ -380,9 +382,9 @@ void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7); if (enable) { - /* - * Do NOT enable flow control until a suitable solution for - * shutting down pause frames is found. + /* + * Do NOT enable flow control until a suitable solution for + * shutting down pause frames is found. */ netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), @@ -464,7 +466,8 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) return 0; } -/* +#if 0 +/* * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts * @param enable 0 means don't enable the port * 1 means enable (or re-enable) the port @@ -544,8 +547,8 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, port, enable); } else { - printk(KERN_ERR PFX "ERROR reading" - "PHY status. Illegal speed.\n"); + printk(KERN_ERR PFX "ERROR reading " + "PHY status. Invalid speed.\n"); result = -1; } } else { @@ -559,13 +562,14 @@ int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, } return result; } +#endif /* 0 */ /* * Return the current station MAC address. * Note that the passed-in value must already be in network byte order. */ -int netxen_niu_macaddr_get(struct netxen_adapter *adapter, - netxen_ethernet_macaddr_t * addr) +static int netxen_niu_macaddr_get(struct netxen_adapter *adapter, + netxen_ethernet_macaddr_t * addr) { u32 stationhigh; u32 stationlow; @@ -619,7 +623,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) return -2; - netxen_niu_macaddr_get(adapter, + netxen_niu_macaddr_get(adapter, (netxen_ethernet_macaddr_t *) mac_addr); if (memcmp(mac_addr, addr, 6) == 0) break; @@ -636,6 +640,7 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter, return 0; } +#if 0 /* Enable a GbE interface */ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, int port, netxen_niu_gbe_ifmode_t mode) @@ -713,6 +718,7 @@ int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, return -EIO; return 0; } +#endif /* 0 */ /* Disable a GbE interface */ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter) @@ -747,7 +753,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) } /* Set promiscuous mode for a GbE interface */ -int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, +int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode) { __u32 reg; @@ -853,6 +859,7 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, return 0; } +#if 0 /* * Return the current station MAC address. * Note that the passed-in value must already be in network byte order. @@ -883,6 +890,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, return 0; } +#endif /* 0 */ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode) diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 10fe6fa..ffa3b72 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2003 - 2006 NetXen, Inc. * All rights reserved. - * + * * 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 @@ -16,10 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA. - * + * * The full GNU General Public License is included in this distribution * in the file called LICENSE. - * + * * Contact Information: * info@netxen.com * NetXen, @@ -30,7 +30,7 @@ #ifndef __NIC_PHAN_REG_H_ #define __NIC_PHAN_REG_H_ -/* +/* * CRB Registers or queue message done only at initialization time. */ #define NIC_CRB_BASE NETXEN_CAM_RAM(0x200) @@ -165,14 +165,7 @@ struct netxen_recv_crb { u32 crb_status_ring_size; }; -#if defined(DEFINE_GLOBAL_RECV_CRB) -#else extern struct netxen_recv_crb recv_crb_registers[]; -extern u64 ctx_addr_sig_regs[][3]; -#endif /* DEFINE_GLOBAL_RECEIVE_CRB */ -#define CRB_CTX_ADDR_REG_LO(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][0]) -#define CRB_CTX_ADDR_REG_HI(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][2]) -#define CRB_CTX_SIGNATURE_REG(FUNC_ID) (ctx_addr_sig_regs[FUNC_ID][1]) /* * Temperature control. diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 816a59e..bb88a41 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -32,9 +32,11 @@ #include #include #include +#include #include #include +#include #include "pasemi_mac.h" @@ -55,9 +57,11 @@ /* Must be a power of two */ -#define RX_RING_SIZE 4096 +#define RX_RING_SIZE 2048 #define TX_RING_SIZE 4096 +#define LRO_MAX_AGGR 64 + #define DEFAULT_MSG_ENABLE \ (NETIF_MSG_DRV | \ NETIF_MSG_PROBE | \ @@ -68,11 +72,11 @@ NETIF_MSG_RX_ERR | \ NETIF_MSG_TX_ERR) -#define TX_RING(mac, num) ((mac)->tx->ring[(num) & (TX_RING_SIZE-1)]) -#define TX_RING_INFO(mac, num) ((mac)->tx->ring_info[(num) & (TX_RING_SIZE-1)]) -#define RX_RING(mac, num) ((mac)->rx->ring[(num) & (RX_RING_SIZE-1)]) -#define RX_RING_INFO(mac, num) ((mac)->rx->ring_info[(num) & (RX_RING_SIZE-1)]) -#define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)]) +#define TX_DESC(tx, num) ((tx)->chan.ring_virt[(num) & (TX_RING_SIZE-1)]) +#define TX_DESC_INFO(tx, num) ((tx)->ring_info[(num) & (TX_RING_SIZE-1)]) +#define RX_DESC(rx, num) ((rx)->chan.ring_virt[(num) & (RX_RING_SIZE-1)]) +#define RX_DESC_INFO(rx, num) ((rx)->ring_info[(num) & (RX_RING_SIZE-1)]) +#define RX_BUFF(rx, num) ((rx)->buffers[(num) & (RX_RING_SIZE-1)]) #define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \ & ((ring)->size - 1)) @@ -88,8 +92,6 @@ static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); -static struct pasdma_status *dma_status; - static int translation_enabled(void) { #if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE) @@ -99,32 +101,78 @@ static int translation_enabled(void) #endif } -static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg, - unsigned int val) +static void write_iob_reg(unsigned int reg, unsigned int val) { - out_le32(mac->iob_regs+reg, val); + pasemi_write_iob_reg(reg, val); } -static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg) +static unsigned int read_mac_reg(const struct pasemi_mac *mac, unsigned int reg) { - return in_le32(mac->regs+reg); + return pasemi_read_mac_reg(mac->dma_if, reg); } -static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg, +static void write_mac_reg(const struct pasemi_mac *mac, unsigned int reg, unsigned int val) { - out_le32(mac->regs+reg, val); + pasemi_write_mac_reg(mac->dma_if, reg, val); } -static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg) +static unsigned int read_dma_reg(unsigned int reg) { - return in_le32(mac->dma_regs+reg); + return pasemi_read_dma_reg(reg); } -static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg, - unsigned int val) +static void write_dma_reg(unsigned int reg, unsigned int val) +{ + pasemi_write_dma_reg(reg, val); +} + +static struct pasemi_mac_rxring *rx_ring(const struct pasemi_mac *mac) { - out_le32(mac->dma_regs+reg, val); + return mac->rx; +} + +static struct pasemi_mac_txring *tx_ring(const struct pasemi_mac *mac) +{ + return mac->tx; +} + +static inline void prefetch_skb(const struct sk_buff *skb) +{ + const void *d = skb; + + prefetch(d); + prefetch(d+64); + prefetch(d+128); + prefetch(d+192); +} + +static int mac_to_intf(struct pasemi_mac *mac) +{ + struct pci_dev *pdev = mac->pdev; + u32 tmp; + int nintf, off, i, j; + int devfn = pdev->devfn; + + tmp = read_dma_reg(PAS_DMA_CAP_IFI); + nintf = (tmp & PAS_DMA_CAP_IFI_NIN_M) >> PAS_DMA_CAP_IFI_NIN_S; + off = (tmp & PAS_DMA_CAP_IFI_IOFF_M) >> PAS_DMA_CAP_IFI_IOFF_S; + + /* IOFF contains the offset to the registers containing the + * DMA interface-to-MAC-pci-id mappings, and NIN contains number + * of total interfaces. Each register contains 4 devfns. + * Just do a linear search until we find the devfn of the MAC + * we're trying to look up. + */ + + for (i = 0; i < (nintf+3)/4; i++) { + tmp = read_dma_reg(off+4*i); + for (j = 0; j < 4; j++) { + if (((tmp >> (8*j)) & 0xff) == devfn) + return i*4 + j; + } + } + return -1; } static int pasemi_get_mac_addr(struct pasemi_mac *mac) @@ -161,7 +209,6 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - if (sscanf(maddr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5]) != 6) { dev_warn(&pdev->dev, @@ -174,21 +221,51 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return 0; } +static int get_skb_hdr(struct sk_buff *skb, void **iphdr, + void **tcph, u64 *hdr_flags, void *data) +{ + u64 macrx = (u64) data; + unsigned int ip_len; + struct iphdr *iph; + + /* IPv4 header checksum failed */ + if ((macrx & XCT_MACRX_HTY_M) != XCT_MACRX_HTY_IPV4_OK) + return -1; + + /* non tcp packet */ + skb_reset_network_header(skb); + iph = ip_hdr(skb); + if (iph->protocol != IPPROTO_TCP) + return -1; + + ip_len = ip_hdrlen(skb); + skb_set_transport_header(skb, ip_len); + *tcph = tcp_hdr(skb); + + /* check if ip header and tcp header are complete */ + if (iph->tot_len < ip_len + tcp_hdrlen(skb)) + return -1; + + *hdr_flags = LRO_IPV4 | LRO_TCP; + *iphdr = iph; + + return 0; +} + static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac, + const int nfrags, struct sk_buff *skb, - dma_addr_t *dmas) + const dma_addr_t *dmas) { int f; - int nfrags = skb_shinfo(skb)->nr_frags; + struct pci_dev *pdev = mac->dma_pdev; - pci_unmap_single(mac->dma_pdev, dmas[0], skb_headlen(skb), - PCI_DMA_TODEVICE); + pci_unmap_single(pdev, dmas[0], skb_headlen(skb), PCI_DMA_TODEVICE); for (f = 0; f < nfrags; f++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[f]; - pci_unmap_page(mac->dma_pdev, dmas[f+1], frag->size, - PCI_DMA_TODEVICE); + pci_unmap_page(pdev, dmas[f+1], frag->size, PCI_DMA_TODEVICE); } dev_kfree_skb_irq(skb); @@ -198,17 +275,21 @@ static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac, return (nfrags + 3) & ~1; } -static int pasemi_mac_setup_rx_resources(struct net_device *dev) +static int pasemi_mac_setup_rx_resources(const struct net_device *dev) { struct pasemi_mac_rxring *ring; struct pasemi_mac *mac = netdev_priv(dev); - int chan_id = mac->dma_rxch; + int chno; unsigned int cfg; - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = pasemi_dma_alloc_chan(RXCHAN, sizeof(struct pasemi_mac_rxring), + offsetof(struct pasemi_mac_rxring, chan)); - if (!ring) - goto out_ring; + if (!ring) { + dev_err(&mac->pdev->dev, "Can't allocate RX channel\n"); + goto out_chan; + } + chno = ring->chan.chno; spin_lock_init(&ring->lock); @@ -220,85 +301,80 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev) goto out_ring_info; /* Allocate descriptors */ - ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(u64), - &ring->dma, GFP_KERNEL); - - if (!ring->ring) + if (pasemi_dma_alloc_ring(&ring->chan, RX_RING_SIZE)) goto out_ring_desc; - memset(ring->ring, 0, RX_RING_SIZE * sizeof(u64)); - ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), &ring->buf_dma, GFP_KERNEL); if (!ring->buffers) - goto out_buffers; + goto out_ring_desc; memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64)); - write_dma_reg(mac, PAS_DMA_RXCHAN_BASEL(chan_id), PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma)); + write_dma_reg(PAS_DMA_RXCHAN_BASEL(chno), + PAS_DMA_RXCHAN_BASEL_BRBL(ring->chan.ring_dma)); - write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id), - PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) | - PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3)); + write_dma_reg(PAS_DMA_RXCHAN_BASEU(chno), + PAS_DMA_RXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32) | + PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3)); cfg = PAS_DMA_RXCHAN_CFG_HBU(2); if (translation_enabled()) cfg |= PAS_DMA_RXCHAN_CFG_CTR; - write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg); + write_dma_reg(PAS_DMA_RXCHAN_CFG(chno), cfg); - write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if), - PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma)); + write_dma_reg(PAS_DMA_RXINT_BASEL(mac->dma_if), + PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma)); - write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if), - PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) | - PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); + write_dma_reg(PAS_DMA_RXINT_BASEU(mac->dma_if), + PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) | + PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3)); - cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 | + cfg = PAS_DMA_RXINT_CFG_DHL(2) | PAS_DMA_RXINT_CFG_L2 | PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP | PAS_DMA_RXINT_CFG_HEN; if (translation_enabled()) cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR; - write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), cfg); + write_dma_reg(PAS_DMA_RXINT_CFG(mac->dma_if), cfg); ring->next_to_fill = 0; ring->next_to_clean = 0; - - snprintf(ring->irq_name, sizeof(ring->irq_name), - "%s rx", dev->name); + ring->mac = mac; mac->rx = ring; return 0; -out_buffers: - dma_free_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(u64), - mac->rx->ring, mac->rx->dma); out_ring_desc: kfree(ring->ring_info); out_ring_info: - kfree(ring); -out_ring: + pasemi_dma_free_chan(&ring->chan); +out_chan: return -ENOMEM; } - -static int pasemi_mac_setup_tx_resources(struct net_device *dev) +static struct pasemi_mac_txring * +pasemi_mac_setup_tx_resources(const struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); u32 val; - int chan_id = mac->dma_txch; struct pasemi_mac_txring *ring; unsigned int cfg; + int chno; + + ring = pasemi_dma_alloc_chan(TXCHAN, sizeof(struct pasemi_mac_txring), + offsetof(struct pasemi_mac_txring, chan)); - ring = kzalloc(sizeof(*ring), GFP_KERNEL); - if (!ring) - goto out_ring; + if (!ring) { + dev_err(&mac->pdev->dev, "Can't allocate TX channel\n"); + goto out_chan; + } + + chno = ring->chan.chno; spin_lock_init(&ring->lock); @@ -309,20 +385,15 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) goto out_ring_info; /* Allocate descriptors */ - ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev, - TX_RING_SIZE * sizeof(u64), - &ring->dma, GFP_KERNEL); - if (!ring->ring) + if (pasemi_dma_alloc_ring(&ring->chan, TX_RING_SIZE)) goto out_ring_desc; - memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64)); - - write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id), - PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma)); - val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32); + write_dma_reg(PAS_DMA_TXCHAN_BASEL(chno), + PAS_DMA_TXCHAN_BASEL_BRBL(ring->chan.ring_dma)); + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->chan.ring_dma >> 32); val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3); - write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val); + write_dma_reg(PAS_DMA_TXCHAN_BASEU(chno), val); cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE | PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) | @@ -332,71 +403,64 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev) if (translation_enabled()) cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR; - write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg); + write_dma_reg(PAS_DMA_TXCHAN_CFG(chno), cfg); ring->next_to_fill = 0; ring->next_to_clean = 0; + ring->mac = mac; - snprintf(ring->irq_name, sizeof(ring->irq_name), - "%s tx", dev->name); - mac->tx = ring; - - return 0; + return ring; out_ring_desc: kfree(ring->ring_info); out_ring_info: - kfree(ring); -out_ring: - return -ENOMEM; + pasemi_dma_free_chan(&ring->chan); +out_chan: + return NULL; } -static void pasemi_mac_free_tx_resources(struct net_device *dev) +static void pasemi_mac_free_tx_resources(struct pasemi_mac *mac) { - struct pasemi_mac *mac = netdev_priv(dev); + struct pasemi_mac_txring *txring = tx_ring(mac); unsigned int i, j; struct pasemi_mac_buffer *info; dma_addr_t dmas[MAX_SKB_FRAGS+1]; - int freed; + int freed, nfrags; int start, limit; - start = mac->tx->next_to_clean; - limit = mac->tx->next_to_fill; + start = txring->next_to_clean; + limit = txring->next_to_fill; /* Compensate for when fill has wrapped and clean has not */ if (start > limit) limit += TX_RING_SIZE; for (i = start; i < limit; i += freed) { - info = &TX_RING_INFO(mac, i+1); + info = &txring->ring_info[(i+1) & (TX_RING_SIZE-1)]; if (info->dma && info->skb) { - for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++) - dmas[j] = TX_RING_INFO(mac, i+1+j).dma; - freed = pasemi_mac_unmap_tx_skb(mac, info->skb, dmas); + nfrags = skb_shinfo(info->skb)->nr_frags; + for (j = 0; j <= nfrags; j++) + dmas[j] = txring->ring_info[(i+1+j) & + (TX_RING_SIZE-1)].dma; + freed = pasemi_mac_unmap_tx_skb(mac, nfrags, + info->skb, dmas); } else freed = 2; } - for (i = 0; i < TX_RING_SIZE; i++) - TX_RING(mac, i) = 0; - - dma_free_coherent(&mac->dma_pdev->dev, - TX_RING_SIZE * sizeof(u64), - mac->tx->ring, mac->tx->dma); + kfree(txring->ring_info); + pasemi_dma_free_chan(&txring->chan); - kfree(mac->tx->ring_info); - kfree(mac->tx); - mac->tx = NULL; } -static void pasemi_mac_free_rx_resources(struct net_device *dev) +static void pasemi_mac_free_rx_resources(struct pasemi_mac *mac) { - struct pasemi_mac *mac = netdev_priv(dev); + struct pasemi_mac_rxring *rx = rx_ring(mac); unsigned int i; struct pasemi_mac_buffer *info; for (i = 0; i < RX_RING_SIZE; i++) { - info = &RX_RING_INFO(mac, i); + info = &RX_DESC_INFO(rx, i); if (info->skb && info->dma) { pci_unmap_single(mac->dma_pdev, info->dma, @@ -409,45 +473,38 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev) } for (i = 0; i < RX_RING_SIZE; i++) - RX_RING(mac, i) = 0; - - dma_free_coherent(&mac->dma_pdev->dev, - RX_RING_SIZE * sizeof(u64), - mac->rx->ring, mac->rx->dma); + RX_DESC(rx, i) = 0; dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64), - mac->rx->buffers, mac->rx->buf_dma); + rx_ring(mac)->buffers, rx_ring(mac)->buf_dma); - kfree(mac->rx->ring_info); - kfree(mac->rx); + kfree(rx_ring(mac)->ring_info); + pasemi_dma_free_chan(&rx_ring(mac)->chan); mac->rx = NULL; } -static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) +static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, + const int limit) { - struct pasemi_mac *mac = netdev_priv(dev); + const struct pasemi_mac *mac = netdev_priv(dev); + struct pasemi_mac_rxring *rx = rx_ring(mac); int fill, count; if (limit <= 0) return; - fill = mac->rx->next_to_fill; + fill = rx_ring(mac)->next_to_fill; for (count = 0; count < limit; count++) { - struct pasemi_mac_buffer *info = &RX_RING_INFO(mac, fill); - u64 *buff = &RX_BUFF(mac, fill); + struct pasemi_mac_buffer *info = &RX_DESC_INFO(rx, fill); + u64 *buff = &RX_BUFF(rx, fill); struct sk_buff *skb; dma_addr_t dma; /* Entry in use? */ WARN_ON(*buff); - /* skb might still be in there for recycle on short receives */ - if (info->skb) - skb = info->skb; - else { - skb = dev_alloc_skb(BUF_SIZE); - skb_reserve(skb, LOCAL_SKB_ALIGN); - } + skb = dev_alloc_skb(BUF_SIZE); + skb_reserve(skb, LOCAL_SKB_ALIGN); if (unlikely(!skb)) break; @@ -469,94 +526,108 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit) wmb(); - write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count); + write_dma_reg(PAS_DMA_RXINT_INCR(mac->dma_if), count); - mac->rx->next_to_fill = (mac->rx->next_to_fill + count) & + rx_ring(mac)->next_to_fill = (rx_ring(mac)->next_to_fill + count) & (RX_RING_SIZE - 1); } -static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) +static void pasemi_mac_restart_rx_intr(const struct pasemi_mac *mac) { + struct pasemi_mac_rxring *rx = rx_ring(mac); unsigned int reg, pcnt; /* Re-enable packet count interrupts: finally * ack the packet count interrupt we got in rx_intr. */ - pcnt = *mac->rx_status & PAS_STATUS_PCNT_M; + pcnt = *rx->chan.status & PAS_STATUS_PCNT_M; reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC; - write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); + if (*rx->chan.status & PAS_STATUS_TIMER) + reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; + + write_iob_reg(PAS_IOB_DMA_RXCH_RESET(mac->rx->chan.chno), reg); } -static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) +static void pasemi_mac_restart_tx_intr(const struct pasemi_mac *mac) { unsigned int reg, pcnt; /* Re-enable packet count interrupts */ - pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; + pcnt = *tx_ring(mac)->chan.status & PAS_STATUS_PCNT_M; reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; - write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); + write_iob_reg(PAS_IOB_DMA_TXCH_RESET(tx_ring(mac)->chan.chno), reg); } -static inline void pasemi_mac_rx_error(struct pasemi_mac *mac, u64 macrx) +static inline void pasemi_mac_rx_error(const struct pasemi_mac *mac, + const u64 macrx) { unsigned int rcmdsta, ccmdsta; + struct pasemi_dmachan *chan = &rx_ring(mac)->chan; if (!netif_msg_rx_err(mac)) return; - rcmdsta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); - ccmdsta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); + rcmdsta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); + ccmdsta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno)); printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n", - macrx, *mac->rx_status); + macrx, *chan->status); printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n", rcmdsta, ccmdsta); } -static inline void pasemi_mac_tx_error(struct pasemi_mac *mac, u64 mactx) +static inline void pasemi_mac_tx_error(const struct pasemi_mac *mac, + const u64 mactx) { unsigned int cmdsta; + struct pasemi_dmachan *chan = &tx_ring(mac)->chan; if (!netif_msg_tx_err(mac)) return; - cmdsta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); + cmdsta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno)); printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\ - "tx status 0x%016lx\n", mactx, *mac->tx_status); + "tx status 0x%016lx\n", mactx, *chan->status); printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta); } -static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) +static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, + const int limit) { + const struct pasemi_dmachan *chan = &rx->chan; + struct pasemi_mac *mac = rx->mac; + struct pci_dev *pdev = mac->dma_pdev; unsigned int n; - int count; + int count, buf_index, tot_bytes, packets; struct pasemi_mac_buffer *info; struct sk_buff *skb; unsigned int len; - u64 macrx; + u64 macrx, eval; dma_addr_t dma; - int buf_index; - u64 eval; - spin_lock(&mac->rx->lock); + tot_bytes = 0; + packets = 0; - n = mac->rx->next_to_clean; + spin_lock(&rx->lock); - prefetch(&RX_RING(mac, n)); + n = rx->next_to_clean; + + prefetch(&RX_DESC(rx, n)); for (count = 0; count < limit; count++) { - macrx = RX_RING(mac, n); + macrx = RX_DESC(rx, n); + prefetch(&RX_DESC(rx, n+4)); if ((macrx & XCT_MACRX_E) || - (*mac->rx_status & PAS_STATUS_ERROR)) + (*chan->status & PAS_STATUS_ERROR)) pasemi_mac_rx_error(mac, macrx); if (!(macrx & XCT_MACRX_O)) @@ -566,21 +637,21 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) BUG_ON(!(macrx & XCT_MACRX_RR_8BRES)); - eval = (RX_RING(mac, n+1) & XCT_RXRES_8B_EVAL_M) >> + eval = (RX_DESC(rx, n+1) & XCT_RXRES_8B_EVAL_M) >> XCT_RXRES_8B_EVAL_S; buf_index = eval-1; - dma = (RX_RING(mac, n+2) & XCT_PTR_ADDR_M); - info = &RX_RING_INFO(mac, buf_index); + dma = (RX_DESC(rx, n+2) & XCT_PTR_ADDR_M); + info = &RX_DESC_INFO(rx, buf_index); skb = info->skb; - prefetch(skb); - prefetch(&skb->data_len); + prefetch_skb(skb); len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; - pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE); + pci_unmap_single(pdev, dma, BUF_SIZE-LOCAL_SKB_ALIGN, + PCI_DMA_FROMDEVICE); if (macrx & XCT_MACRX_CRC) { /* CRC error flagged */ @@ -590,26 +661,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) goto next; } - if (len < 256) { - struct sk_buff *new_skb; - - new_skb = netdev_alloc_skb(mac->netdev, - len + LOCAL_SKB_ALIGN); - if (new_skb) { - skb_reserve(new_skb, LOCAL_SKB_ALIGN); - memcpy(new_skb->data, skb->data, len); - /* save the skb in buffer_info as good */ - skb = new_skb; - } - /* else just continue with the old one */ - } else - info->skb = NULL; - + info->skb = NULL; info->dma = 0; - /* Don't include CRC */ - skb_put(skb, len-4); - if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) { skb->ip_summed = CHECKSUM_UNNECESSARY; skb->csum = (macrx & XCT_MACRX_CSUM_M) >> @@ -617,41 +671,49 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) } else skb->ip_summed = CHECKSUM_NONE; - mac->netdev->stats.rx_bytes += len; - mac->netdev->stats.rx_packets++; + packets++; + tot_bytes += len; + + /* Don't include CRC */ + skb_put(skb, len-4); skb->protocol = eth_type_trans(skb, mac->netdev); - netif_receive_skb(skb); + lro_receive_skb(&mac->lro_mgr, skb, (void *)macrx); next: - RX_RING(mac, n) = 0; - RX_RING(mac, n+1) = 0; + RX_DESC(rx, n) = 0; + RX_DESC(rx, n+1) = 0; /* Need to zero it out since hardware doesn't, since the * replenish loop uses it to tell when it's done. */ - RX_BUFF(mac, buf_index) = 0; + RX_BUFF(rx, buf_index) = 0; n += 4; } if (n > RX_RING_SIZE) { /* Errata 5971 workaround: L2 target of headers */ - write_iob_reg(mac, PAS_IOB_COM_PKTHDRCNT, 0); + write_iob_reg(PAS_IOB_COM_PKTHDRCNT, 0); n &= (RX_RING_SIZE-1); } - mac->rx->next_to_clean = n; + rx_ring(mac)->next_to_clean = n; + + lro_flush_all(&mac->lro_mgr); /* Increase is in number of 16-byte entries, and since each descriptor * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with * count*2. */ - write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), count << 1); + write_dma_reg(PAS_DMA_RXCHAN_INCR(mac->rx->chan.chno), count << 1); pasemi_mac_replenish_rx_ring(mac->netdev, count); - spin_unlock(&mac->rx->lock); + mac->netdev->stats.rx_bytes += tot_bytes; + mac->netdev->stats.rx_packets += packets; + + spin_unlock(&rx_ring(mac)->lock); return count; } @@ -659,8 +721,10 @@ next: /* Can't make this too large or we blow the kernel stack limits */ #define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS) -static int pasemi_mac_clean_tx(struct pasemi_mac *mac) +static int pasemi_mac_clean_tx(struct pasemi_mac_txring *txring) { + struct pasemi_dmachan *chan = &txring->chan; + struct pasemi_mac *mac = txring->mac; int i, j; unsigned int start, descr_count, buf_count, batch_limit; unsigned int ring_limit; @@ -668,14 +732,18 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac) unsigned long flags; struct sk_buff *skbs[TX_CLEAN_BATCHSIZE]; dma_addr_t dmas[TX_CLEAN_BATCHSIZE][MAX_SKB_FRAGS+1]; + int nf[TX_CLEAN_BATCHSIZE]; + int nr_frags; total_count = 0; batch_limit = TX_CLEAN_BATCHSIZE; restart: - spin_lock_irqsave(&mac->tx->lock, flags); + spin_lock_irqsave(&txring->lock, flags); + + start = txring->next_to_clean; + ring_limit = txring->next_to_fill; - start = mac->tx->next_to_clean; - ring_limit = mac->tx->next_to_fill; + prefetch(&TX_DESC_INFO(txring, start+1).skb); /* Compensate for when fill has wrapped but clean has not */ if (start > ring_limit) @@ -687,41 +755,45 @@ restart: for (i = start; descr_count < batch_limit && i < ring_limit; i += buf_count) { - u64 mactx = TX_RING(mac, i); + u64 mactx = TX_DESC(txring, i); struct sk_buff *skb; + skb = TX_DESC_INFO(txring, i+1).skb; + nr_frags = TX_DESC_INFO(txring, i).dma; + if ((mactx & XCT_MACTX_E) || - (*mac->tx_status & PAS_STATUS_ERROR)) + (*chan->status & PAS_STATUS_ERROR)) pasemi_mac_tx_error(mac, mactx); if (unlikely(mactx & XCT_MACTX_O)) /* Not yet transmitted */ break; - skb = TX_RING_INFO(mac, i+1).skb; - skbs[descr_count] = skb; - - buf_count = 2 + skb_shinfo(skb)->nr_frags; - for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++) - dmas[descr_count][j] = TX_RING_INFO(mac, i+1+j).dma; - - TX_RING(mac, i) = 0; - TX_RING(mac, i+1) = 0; - + buf_count = 2 + nr_frags; /* Since we always fill with an even number of entries, make * sure we skip any unused one at the end as well. */ if (buf_count & 1) buf_count++; + + for (j = 0; j <= nr_frags; j++) + dmas[descr_count][j] = TX_DESC_INFO(txring, i+1+j).dma; + + skbs[descr_count] = skb; + nf[descr_count] = nr_frags; + + TX_DESC(txring, i) = 0; + TX_DESC(txring, i+1) = 0; + descr_count++; } - mac->tx->next_to_clean = i & (TX_RING_SIZE-1); + txring->next_to_clean = i & (TX_RING_SIZE-1); - spin_unlock_irqrestore(&mac->tx->lock, flags); + spin_unlock_irqrestore(&txring->lock, flags); netif_wake_queue(mac->netdev); for (i = 0; i < descr_count; i++) - pasemi_mac_unmap_tx_skb(mac, skbs[i], dmas[i]); + pasemi_mac_unmap_tx_skb(mac, nf[i], skbs[i], dmas[i]); total_count += descr_count; @@ -735,11 +807,13 @@ restart: static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) { - struct net_device *dev = data; - struct pasemi_mac *mac = netdev_priv(dev); + const struct pasemi_mac_rxring *rxring = data; + struct pasemi_mac *mac = rxring->mac; + struct net_device *dev = mac->netdev; + const struct pasemi_dmachan *chan = &rxring->chan; unsigned int reg; - if (!(*mac->rx_status & PAS_STATUS_CAUSE_M)) + if (!(*chan->status & PAS_STATUS_CAUSE_M)) return IRQ_NONE; /* Don't reset packet count so it won't fire again but clear @@ -747,45 +821,77 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) */ reg = 0; - if (*mac->rx_status & PAS_STATUS_SOFT) + if (*chan->status & PAS_STATUS_SOFT) reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; - if (*mac->rx_status & PAS_STATUS_ERROR) + if (*chan->status & PAS_STATUS_ERROR) reg |= PAS_IOB_DMA_RXCH_RESET_DINTC; - if (*mac->rx_status & PAS_STATUS_TIMER) - reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; netif_rx_schedule(dev, &mac->napi); - write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); + write_iob_reg(PAS_IOB_DMA_RXCH_RESET(chan->chno), reg); return IRQ_HANDLED; } -static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) +#define TX_CLEAN_INTERVAL HZ + +static void pasemi_mac_tx_timer(unsigned long data) { - struct net_device *dev = data; - struct pasemi_mac *mac = netdev_priv(dev); - unsigned int reg, pcnt; + struct pasemi_mac_txring *txring = (struct pasemi_mac_txring *)data; + struct pasemi_mac *mac = txring->mac; - if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) - return IRQ_NONE; + pasemi_mac_clean_tx(txring); + + mod_timer(&txring->clean_timer, jiffies + TX_CLEAN_INTERVAL); - pasemi_mac_clean_tx(mac); + pasemi_mac_restart_tx_intr(mac); +} - pcnt = *mac->tx_status & PAS_STATUS_PCNT_M; +static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) +{ + struct pasemi_mac_txring *txring = data; + const struct pasemi_dmachan *chan = &txring->chan; + struct pasemi_mac *mac = txring->mac; + unsigned int reg; - reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC; + if (!(*chan->status & PAS_STATUS_CAUSE_M)) + return IRQ_NONE; - if (*mac->tx_status & PAS_STATUS_SOFT) + reg = 0; + + if (*chan->status & PAS_STATUS_SOFT) reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; - if (*mac->tx_status & PAS_STATUS_ERROR) + if (*chan->status & PAS_STATUS_ERROR) reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; - write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); + mod_timer(&txring->clean_timer, jiffies + (TX_CLEAN_INTERVAL)*2); + + netif_rx_schedule(mac->netdev, &mac->napi); + + if (reg) + write_iob_reg(PAS_IOB_DMA_TXCH_RESET(chan->chno), reg); return IRQ_HANDLED; } +static void pasemi_mac_intf_disable(struct pasemi_mac *mac) +{ + unsigned int flags; + + flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); + flags &= ~PAS_MAC_CFG_PCFG_PE; + write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags); +} + +static void pasemi_mac_intf_enable(struct pasemi_mac *mac) +{ + unsigned int flags; + + flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); + flags |= PAS_MAC_CFG_PCFG_PE; + write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags); +} + static void pasemi_adjust_link(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); @@ -801,11 +907,14 @@ static void pasemi_adjust_link(struct net_device *dev) printk(KERN_INFO "%s: Link is down.\n", dev->name); netif_carrier_off(dev); + pasemi_mac_intf_disable(mac); mac->link = 0; return; - } else + } else { + pasemi_mac_intf_enable(mac); netif_carrier_on(dev); + } flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M | @@ -897,15 +1006,14 @@ err: static int pasemi_mac_open(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); - int base_irq; unsigned int flags; int ret; /* enable rx section */ - write_dma_reg(mac, PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN); + write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN); /* enable tx section */ - write_dma_reg(mac, PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN); + write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN); flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) | PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) | @@ -913,62 +1021,59 @@ static int pasemi_mac_open(struct net_device *dev) write_mac_reg(mac, PAS_MAC_CFG_TXP, flags); - write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); + ret = pasemi_mac_setup_rx_resources(dev); + if (ret) + goto out_rx_resources; - write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), - PAS_IOB_DMA_TXCH_CFG_CNTTH(128)); + mac->tx = pasemi_mac_setup_tx_resources(dev); - /* Clear out any residual packet count state from firmware */ - pasemi_mac_restart_rx_intr(mac); - pasemi_mac_restart_tx_intr(mac); + if (!mac->tx) + goto out_tx_ring; - /* 0xffffff is max value, about 16ms */ - write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); + /* 0x3ff with 33MHz clock is about 31us */ + write_iob_reg(PAS_IOB_DMA_COM_TIMEOUTCFG, + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0x3ff)); - ret = pasemi_mac_setup_rx_resources(dev); - if (ret) - goto out_rx_resources; + write_iob_reg(PAS_IOB_DMA_RXCH_CFG(mac->rx->chan.chno), + PAS_IOB_DMA_RXCH_CFG_CNTTH(256)); - ret = pasemi_mac_setup_tx_resources(dev); - if (ret) - goto out_tx_resources; + write_iob_reg(PAS_IOB_DMA_TXCH_CFG(mac->tx->chan.chno), + PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); write_mac_reg(mac, PAS_MAC_IPC_CHNL, - PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) | - PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch)); + PAS_MAC_IPC_CHNL_DCHNO(mac->rx->chan.chno) | + PAS_MAC_IPC_CHNL_BCH(mac->rx->chan.chno)); /* enable rx if */ - write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), - PAS_DMA_RXINT_RCMDSTA_EN | - PAS_DMA_RXINT_RCMDSTA_DROPS_M | - PAS_DMA_RXINT_RCMDSTA_BP | - PAS_DMA_RXINT_RCMDSTA_OO | - PAS_DMA_RXINT_RCMDSTA_BT); + write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), + PAS_DMA_RXINT_RCMDSTA_EN | + PAS_DMA_RXINT_RCMDSTA_DROPS_M | + PAS_DMA_RXINT_RCMDSTA_BP | + PAS_DMA_RXINT_RCMDSTA_OO | + PAS_DMA_RXINT_RCMDSTA_BT); /* enable rx channel */ - write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), - PAS_DMA_RXCHAN_CCMDSTA_EN | - PAS_DMA_RXCHAN_CCMDSTA_DU | - PAS_DMA_RXCHAN_CCMDSTA_OD | - PAS_DMA_RXCHAN_CCMDSTA_FD | - PAS_DMA_RXCHAN_CCMDSTA_DT); + pasemi_dma_start_chan(&rx_ring(mac)->chan, PAS_DMA_RXCHAN_CCMDSTA_DU | + PAS_DMA_RXCHAN_CCMDSTA_OD | + PAS_DMA_RXCHAN_CCMDSTA_FD | + PAS_DMA_RXCHAN_CCMDSTA_DT); /* enable tx channel */ - write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), - PAS_DMA_TXCHAN_TCMDSTA_EN | - PAS_DMA_TXCHAN_TCMDSTA_SZ | - PAS_DMA_TXCHAN_TCMDSTA_DB | - PAS_DMA_TXCHAN_TCMDSTA_DE | - PAS_DMA_TXCHAN_TCMDSTA_DA); + pasemi_dma_start_chan(&tx_ring(mac)->chan, PAS_DMA_TXCHAN_TCMDSTA_SZ | + PAS_DMA_TXCHAN_TCMDSTA_DB | + PAS_DMA_TXCHAN_TCMDSTA_DE | + PAS_DMA_TXCHAN_TCMDSTA_DA); pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE); - write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), RX_RING_SIZE>>1); + write_dma_reg(PAS_DMA_RXCHAN_INCR(rx_ring(mac)->chan.chno), + RX_RING_SIZE>>1); + + /* Clear out any residual packet count state from firmware */ + pasemi_mac_restart_rx_intr(mac); + pasemi_mac_restart_tx_intr(mac); - flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE | - PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; + flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE; if (mac->type == MAC_TYPE_GMAC) flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; @@ -979,55 +1084,63 @@ static int pasemi_mac_open(struct net_device *dev) write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags); ret = pasemi_mac_phy_init(dev); - /* Some configs don't have PHYs (XAUI etc), so don't complain about - * failed init due to -ENODEV. - */ - if (ret && ret != -ENODEV) - dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret); + if (ret) { + /* Since we won't get link notification, just enable RX */ + pasemi_mac_intf_enable(mac); + if (mac->type == MAC_TYPE_GMAC) { + /* Warn for missing PHY on SGMII (1Gig) ports */ + dev_warn(&mac->pdev->dev, + "PHY init failed: %d.\n", ret); + dev_warn(&mac->pdev->dev, + "Defaulting to 1Gbit full duplex\n"); + } + } netif_start_queue(dev); napi_enable(&mac->napi); - /* Interrupts are a bit different for our DMA controller: While - * it's got one a regular PCI device header, the interrupt there - * is really the base of the range it's using. Each tx and rx - * channel has it's own interrupt source. - */ - - base_irq = virq_to_hw(mac->dma_pdev->irq); + snprintf(mac->tx_irq_name, sizeof(mac->tx_irq_name), "%s tx", + dev->name); - mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch); - mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch); - - ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED, - mac->tx->irq_name, dev); + ret = request_irq(mac->tx->chan.irq, &pasemi_mac_tx_intr, IRQF_DISABLED, + mac->tx_irq_name, mac->tx); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - base_irq + mac->dma_txch, ret); + mac->tx->chan.irq, ret); goto out_tx_int; } - ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED, - mac->rx->irq_name, dev); + snprintf(mac->rx_irq_name, sizeof(mac->rx_irq_name), "%s rx", + dev->name); + + ret = request_irq(mac->rx->chan.irq, &pasemi_mac_rx_intr, IRQF_DISABLED, + mac->rx_irq_name, mac->rx); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - base_irq + 20 + mac->dma_rxch, ret); + mac->rx->chan.irq, ret); goto out_rx_int; } if (mac->phydev) phy_start(mac->phydev); + init_timer(&mac->tx->clean_timer); + mac->tx->clean_timer.function = pasemi_mac_tx_timer; + mac->tx->clean_timer.data = (unsigned long)mac->tx; + mac->tx->clean_timer.expires = jiffies+HZ; + add_timer(&mac->tx->clean_timer); + return 0; out_rx_int: - free_irq(mac->tx_irq, dev); + free_irq(mac->tx->chan.irq, mac->tx); out_tx_int: napi_disable(&mac->napi); netif_stop_queue(dev); - pasemi_mac_free_tx_resources(dev); -out_tx_resources: - pasemi_mac_free_rx_resources(dev); +out_tx_ring: + if (mac->tx) + pasemi_mac_free_tx_resources(mac); + pasemi_mac_free_rx_resources(mac); out_rx_resources: return ret; @@ -1040,46 +1153,53 @@ static int pasemi_mac_close(struct net_device *dev) struct pasemi_mac *mac = netdev_priv(dev); unsigned int sta; int retries; + int rxch, txch; + + rxch = rx_ring(mac)->chan.chno; + txch = tx_ring(mac)->chan.chno; if (mac->phydev) { phy_stop(mac->phydev); phy_disconnect(mac->phydev); } + del_timer_sync(&mac->tx->clean_timer); + netif_stop_queue(dev); napi_disable(&mac->napi); - sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); + sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); if (sta & (PAS_DMA_RXINT_RCMDSTA_BP | PAS_DMA_RXINT_RCMDSTA_OO | PAS_DMA_RXINT_RCMDSTA_BT)) printk(KERN_DEBUG "pasemi_mac: rcmdsta error: 0x%08x\n", sta); - sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); + sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch)); if (sta & (PAS_DMA_RXCHAN_CCMDSTA_DU | PAS_DMA_RXCHAN_CCMDSTA_OD | PAS_DMA_RXCHAN_CCMDSTA_FD | PAS_DMA_RXCHAN_CCMDSTA_DT)) printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta); - sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); - if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | - PAS_DMA_TXCHAN_TCMDSTA_DB | - PAS_DMA_TXCHAN_TCMDSTA_DE | - PAS_DMA_TXCHAN_TCMDSTA_DA)) + sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch)); + if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ | PAS_DMA_TXCHAN_TCMDSTA_DB | + PAS_DMA_TXCHAN_TCMDSTA_DE | PAS_DMA_TXCHAN_TCMDSTA_DA)) printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta); /* Clean out any pending buffers */ - pasemi_mac_clean_tx(mac); - pasemi_mac_clean_rx(mac, RX_RING_SIZE); + pasemi_mac_clean_tx(tx_ring(mac)); + pasemi_mac_clean_rx(rx_ring(mac), RX_RING_SIZE); /* Disable interface */ - write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST); - write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST); - write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST); + write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), + PAS_DMA_TXCHAN_TCMDSTA_ST); + write_dma_reg( PAS_DMA_RXINT_RCMDSTA(mac->dma_if), + PAS_DMA_RXINT_RCMDSTA_ST); + write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), + PAS_DMA_RXCHAN_CCMDSTA_ST); for (retries = 0; retries < MAX_RETRIES; retries++) { - sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch)); + sta = read_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(rxch)); if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) break; cond_resched(); @@ -1089,7 +1209,7 @@ static int pasemi_mac_close(struct net_device *dev) dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); for (retries = 0; retries < MAX_RETRIES; retries++) { - sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch)); + sta = read_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch)); if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) break; cond_resched(); @@ -1099,7 +1219,7 @@ static int pasemi_mac_close(struct net_device *dev) dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n"); for (retries = 0; retries < MAX_RETRIES; retries++) { - sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); + sta = read_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if)); if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT)) break; cond_resched(); @@ -1112,16 +1232,16 @@ static int pasemi_mac_close(struct net_device *dev) * stopping, since you can't disable when active. */ - write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0); - write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0); - write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); + write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(txch), 0); + write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(rxch), 0); + write_dma_reg(PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); - free_irq(mac->tx_irq, dev); - free_irq(mac->rx_irq, dev); + free_irq(mac->tx->chan.irq, mac->tx); + free_irq(mac->rx->chan.irq, mac->rx); /* Free resources */ - pasemi_mac_free_rx_resources(dev); - pasemi_mac_free_tx_resources(dev); + pasemi_mac_free_rx_resources(mac); + pasemi_mac_free_tx_resources(mac); return 0; } @@ -1135,6 +1255,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) unsigned int map_size[MAX_SKB_FRAGS+1]; unsigned long flags; int i, nfrags; + int fill; dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_CRC_PAD; @@ -1178,10 +1299,12 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) mactx = dflags | XCT_MACTX_LLEN(skb->len); - txring = mac->tx; + txring = tx_ring(mac); spin_lock_irqsave(&txring->lock, flags); + fill = txring->next_to_fill; + /* Avoid stepping on the same cache line that the DMA controller * is currently about to send, so leave at least 8 words available. * Total free space needed is mactx + fragments + 8 @@ -1192,13 +1315,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) goto out_err; } - TX_RING(mac, txring->next_to_fill) = mactx; - txring->next_to_fill++; - TX_RING_INFO(mac, txring->next_to_fill).skb = skb; + TX_DESC(txring, fill) = mactx; + TX_DESC_INFO(txring, fill).dma = nfrags; + fill++; + TX_DESC_INFO(txring, fill).skb = skb; for (i = 0; i <= nfrags; i++) { - TX_RING(mac, txring->next_to_fill+i) = - XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]); - TX_RING_INFO(mac, txring->next_to_fill+i).dma = map[i]; + TX_DESC(txring, fill+i) = + XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]); + TX_DESC_INFO(txring, fill+i).dma = map[i]; } /* We have to add an even number of 8-byte entries to the ring @@ -1208,15 +1332,14 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) if (nfrags & 1) nfrags++; - txring->next_to_fill = (txring->next_to_fill + nfrags + 1) & - (TX_RING_SIZE-1); + txring->next_to_fill = (fill + nfrags + 1) & (TX_RING_SIZE-1); dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; spin_unlock_irqrestore(&txring->lock, flags); - write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), (nfrags+2) >> 1); + write_dma_reg(PAS_DMA_TXCHAN_INCR(txring->chan.chno), (nfrags+2) >> 1); return NETDEV_TX_OK; @@ -1232,7 +1355,7 @@ out_err_nolock: static void pasemi_mac_set_rx_mode(struct net_device *dev) { - struct pasemi_mac *mac = netdev_priv(dev); + const struct pasemi_mac *mac = netdev_priv(dev); unsigned int flags; flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG); @@ -1253,88 +1376,21 @@ static int pasemi_mac_poll(struct napi_struct *napi, int budget) struct net_device *dev = mac->netdev; int pkts; - pasemi_mac_clean_tx(mac); - pkts = pasemi_mac_clean_rx(mac, budget); + pasemi_mac_clean_tx(tx_ring(mac)); + pkts = pasemi_mac_clean_rx(rx_ring(mac), budget); if (pkts < budget) { /* all done, no more packets present */ netif_rx_complete(dev, napi); pasemi_mac_restart_rx_intr(mac); + pasemi_mac_restart_tx_intr(mac); } return pkts; } -static void __iomem * __devinit map_onedev(struct pci_dev *p, int index) -{ - struct device_node *dn; - void __iomem *ret; - - dn = pci_device_to_OF_node(p); - if (!dn) - goto fallback; - - ret = of_iomap(dn, index); - if (!ret) - goto fallback; - - return ret; -fallback: - /* This is hardcoded and ugly, but we have some firmware versions - * that don't provide the register space in the device tree. Luckily - * they are at well-known locations so we can just do the math here. - */ - return ioremap(0xe0000000 + (p->devfn << 12), 0x2000); -} - -static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac) -{ - struct resource res; - struct device_node *dn; - int err; - - mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); - if (!mac->dma_pdev) { - dev_err(&mac->pdev->dev, "Can't find DMA Controller\n"); - return -ENODEV; - } - - mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); - if (!mac->iob_pdev) { - dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n"); - return -ENODEV; - } - - mac->regs = map_onedev(mac->pdev, 0); - mac->dma_regs = map_onedev(mac->dma_pdev, 0); - mac->iob_regs = map_onedev(mac->iob_pdev, 0); - - if (!mac->regs || !mac->dma_regs || !mac->iob_regs) { - dev_err(&mac->pdev->dev, "Can't map registers\n"); - return -ENODEV; - } - - /* The dma status structure is located in the I/O bridge, and - * is cache coherent. - */ - if (!dma_status) { - dn = pci_device_to_OF_node(mac->iob_pdev); - if (dn) - err = of_address_to_resource(dn, 1, &res); - if (!dn || err) { - /* Fallback for old firmware */ - res.start = 0xfd800000; - res.end = res.start + 0x1000; - } - dma_status = __ioremap(res.start, res.end-res.start, 0); - } - - return 0; -} - static int __devinit pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int index = 0; struct net_device *dev; struct pasemi_mac *mac; int err; @@ -1362,20 +1418,46 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64); - dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG; + dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG | + NETIF_F_HIGHDMA; - /* These should come out of the device tree eventually */ - mac->dma_txch = index; - mac->dma_rxch = index; + mac->lro_mgr.max_aggr = LRO_MAX_AGGR; + mac->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS; + mac->lro_mgr.lro_arr = mac->lro_desc; + mac->lro_mgr.get_skb_header = get_skb_hdr; + mac->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID; + mac->lro_mgr.dev = mac->netdev; + mac->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY; + mac->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; - /* We probe GMAC before XAUI, but the DMA interfaces are - * in XAUI, GMAC order. - */ - if (index < 4) - mac->dma_if = index + 2; - else - mac->dma_if = index - 4; - index++; + + mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); + if (!mac->dma_pdev) { + dev_err(&mac->pdev->dev, "Can't find DMA Controller\n"); + err = -ENODEV; + goto out; + } + + mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL); + if (!mac->iob_pdev) { + dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n"); + err = -ENODEV; + goto out; + } + + /* get mac addr from device tree */ + if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) { + err = -ENODEV; + goto out; + } + memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr)); + + mac->dma_if = mac_to_intf(mac); + if (mac->dma_if < 0) { + dev_err(&mac->pdev->dev, "Can't map DMA interface\n"); + err = -ENODEV; + goto out; + } switch (pdev->device) { case 0xa005: @@ -1389,25 +1471,14 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto out; } - /* get mac addr from device tree */ - if (pasemi_get_mac_addr(mac) || !is_valid_ether_addr(mac->mac_addr)) { - err = -ENODEV; - goto out; - } - memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr)); - dev->open = pasemi_mac_open; dev->stop = pasemi_mac_close; dev->hard_start_xmit = pasemi_mac_start_tx; dev->set_multicast_list = pasemi_mac_set_rx_mode; - err = pasemi_mac_map_regs(mac); if (err) goto out; - mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; - mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; - mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); /* Enable most messages by default */ @@ -1420,11 +1491,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err); goto out; } else if netif_msg_probe(mac) - printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, " - "hw addr %s\n", + printk(KERN_INFO "%s: PA Semi %s: intf %d, hw addr %s\n", dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI", - mac->dma_if, mac->dma_txch, mac->dma_rxch, - print_mac(mac_buf, dev->dev_addr)); + mac->dma_if, print_mac(mac_buf, dev->dev_addr)); return err; @@ -1433,12 +1502,6 @@ out: pci_dev_put(mac->iob_pdev); if (mac->dma_pdev) pci_dev_put(mac->dma_pdev); - if (mac->dma_regs) - iounmap(mac->dma_regs); - if (mac->iob_regs) - iounmap(mac->iob_regs); - if (mac->regs) - iounmap(mac->regs); free_netdev(dev); out_disable_device: @@ -1463,9 +1526,8 @@ static void __devexit pasemi_mac_remove(struct pci_dev *pdev) pci_dev_put(mac->dma_pdev); pci_dev_put(mac->iob_pdev); - iounmap(mac->regs); - iounmap(mac->dma_regs); - iounmap(mac->iob_regs); + pasemi_dma_free_chan(&mac->tx->chan); + pasemi_dma_free_chan(&mac->rx->chan); pci_set_drvdata(pdev, NULL); free_netdev(netdev); @@ -1489,12 +1551,16 @@ static struct pci_driver pasemi_mac_driver = { static void __exit pasemi_mac_cleanup_module(void) { pci_unregister_driver(&pasemi_mac_driver); - __iounmap(dma_status); - dma_status = NULL; } int pasemi_mac_init_module(void) { + int err; + + err = pasemi_dma_init(); + if (err) + return err; + return pci_register_driver(&pasemi_mac_driver); } diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 60368df..8bee2a6 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -26,60 +26,55 @@ #include #include +#define MAX_LRO_DESCRIPTORS 8 + struct pasemi_mac_txring { + struct pasemi_dmachan chan; /* Must be first */ spinlock_t lock; - u64 *ring; - dma_addr_t dma; unsigned int size; unsigned int next_to_fill; unsigned int next_to_clean; struct pasemi_mac_buffer *ring_info; - char irq_name[10]; /* "eth%d tx" */ + struct pasemi_mac *mac; /* Needed in intr handler */ + struct timer_list clean_timer; }; struct pasemi_mac_rxring { + struct pasemi_dmachan chan; /* Must be first */ spinlock_t lock; - u64 *ring; /* RX channel descriptor ring */ - dma_addr_t dma; u64 *buffers; /* RX interface buffer ring */ dma_addr_t buf_dma; unsigned int size; unsigned int next_to_fill; unsigned int next_to_clean; struct pasemi_mac_buffer *ring_info; - char irq_name[10]; /* "eth%d rx" */ + struct pasemi_mac *mac; /* Needed in intr handler */ }; struct pasemi_mac { struct net_device *netdev; - void __iomem *regs; - void __iomem *dma_regs; - void __iomem *iob_regs; struct pci_dev *pdev; struct pci_dev *dma_pdev; struct pci_dev *iob_pdev; struct phy_device *phydev; struct napi_struct napi; - /* Pointer to the cacheable per-channel status registers */ - u64 *rx_status; - u64 *tx_status; - u8 type; #define MAC_TYPE_GMAC 1 #define MAC_TYPE_XAUI 2 - u32 dma_txch; u32 dma_if; - u32 dma_rxch; u8 mac_addr[6]; + struct net_lro_mgr lro_mgr; + struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS]; struct timer_list rxtimer; + unsigned int lro_max_aggr; struct pasemi_mac_txring *tx; struct pasemi_mac_rxring *rx; - unsigned long tx_irq; - unsigned long rx_irq; + char tx_irq_name[10]; /* "eth%d tx" */ + char rx_irq_name[10]; /* "eth%d rx" */ int link; int speed; int duplex; @@ -95,11 +90,8 @@ struct pasemi_mac_buffer { }; -/* status register layout in IOB region, at 0xfb800000 */ -struct pasdma_status { - u64 rx_sta[64]; - u64 tx_sta[20]; -}; +/* PCI register offsets and formats */ + /* MAC CFG register offsets */ enum { @@ -173,333 +165,4 @@ enum { #define PAS_MAC_IPC_CHNL_BCH(x) (((x) << PAS_MAC_IPC_CHNL_BCH_S) & \ PAS_MAC_IPC_CHNL_BCH_M) -/* All these registers live in the PCI configuration space for the DMA PCI - * device. Use the normal PCI config access functions for them. - */ -enum { - PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */ - PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */ - PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */ - PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */ -}; -#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */ -#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */ -#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */ -#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */ - - -/* Per-interface and per-channel registers */ -#define _PAS_DMA_RXINT_STRIDE 0x20 -#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001 -#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002 -#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008 -#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010 -#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020 -#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040 -#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800 -#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000 -#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000 -#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000 -#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000 -#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 -#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 -#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 -#define PAS_DMA_RXINT_CFG(i) (0x204+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_CFG_RBP 0x80000000 -#define PAS_DMA_RXINT_CFG_ITRR 0x40000000 -#define PAS_DMA_RXINT_CFG_DHL_M 0x07000000 -#define PAS_DMA_RXINT_CFG_DHL_S 24 -#define PAS_DMA_RXINT_CFG_DHL(x) (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \ - PAS_DMA_RXINT_CFG_DHL_M) -#define PAS_DMA_RXINT_CFG_ITR 0x00400000 -#define PAS_DMA_RXINT_CFG_LW 0x00200000 -#define PAS_DMA_RXINT_CFG_L2 0x00100000 -#define PAS_DMA_RXINT_CFG_HEN 0x00080000 -#define PAS_DMA_RXINT_CFG_WIF 0x00000002 -#define PAS_DMA_RXINT_CFG_WIL 0x00000001 - -#define PAS_DMA_RXINT_INCR(i) (0x210+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_INCR_INCR_M 0x0000ffff -#define PAS_DMA_RXINT_INCR_INCR_S 0 -#define PAS_DMA_RXINT_INCR_INCR(x) ((x) & 0x0000ffff) -#define PAS_DMA_RXINT_BASEL(i) (0x218+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_BASEL_BRBL(x) ((x) & ~0x3f) -#define PAS_DMA_RXINT_BASEU(i) (0x21c+(i)*_PAS_DMA_RXINT_STRIDE) -#define PAS_DMA_RXINT_BASEU_BRBH(x) ((x) & 0xfff) -#define PAS_DMA_RXINT_BASEU_SIZ_M 0x3fff0000 /* # of cache lines worth of buffer ring */ -#define PAS_DMA_RXINT_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_RXINT_BASEU_SIZ(x) (((x) << PAS_DMA_RXINT_BASEU_SIZ_S) & \ - PAS_DMA_RXINT_BASEU_SIZ_M) - - -#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */ -#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */ -#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */ -#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */ -#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */ -#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */ -#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */ -#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */ -#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */ -#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */ -#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */ -#define PAS_DMA_TXCHAN_TCMDSTA_SZ 0x00000800 -#define PAS_DMA_TXCHAN_TCMDSTA_DB 0x00000400 -#define PAS_DMA_TXCHAN_TCMDSTA_DE 0x00000200 -#define PAS_DMA_TXCHAN_TCMDSTA_DA 0x00000100 -#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */ -#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c -#define PAS_DMA_TXCHAN_CFG_TATTR_S 2 -#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \ - PAS_DMA_TXCHAN_CFG_TATTR_M) -#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0 -#define PAS_DMA_TXCHAN_CFG_WT_S 6 -#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \ - PAS_DMA_TXCHAN_CFG_WT_M) -#define PAS_DMA_TXCHAN_CFG_TRD 0x00010000 /* translate data */ -#define PAS_DMA_TXCHAN_CFG_TRR 0x00008000 /* translate rings */ -#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */ -#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */ -#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */ -#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0 -#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0 -#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \ - PAS_DMA_TXCHAN_BASEL_BRBL_M) -#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE) -#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff -#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0 -#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \ - PAS_DMA_TXCHAN_BASEU_BRBH_M) -/* # of cache lines worth of buffer ring */ -#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000 -#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \ - PAS_DMA_TXCHAN_BASEU_SIZ_M) - -#define _PAS_DMA_RXCHAN_STRIDE 0x20 /* Size per channel */ -#define _PAS_DMA_RXCHAN_CCMDSTA 0x800 /* Command / Status */ -#define _PAS_DMA_RXCHAN_CFG 0x804 /* Configuration */ -#define _PAS_DMA_RXCHAN_INCR 0x810 /* Descriptor increment */ -#define _PAS_DMA_RXCHAN_CNT 0x814 /* Descriptor count/offset */ -#define _PAS_DMA_RXCHAN_BASEL 0x818 /* Descriptor ring base (low) */ -#define _PAS_DMA_RXCHAN_BASEU 0x81c /* (high) */ -#define PAS_DMA_RXCHAN_CCMDSTA(c) (0x800+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_CCMDSTA_EN 0x00000001 /* Enabled */ -#define PAS_DMA_RXCHAN_CCMDSTA_ST 0x00000002 /* Stop interface */ -#define PAS_DMA_RXCHAN_CCMDSTA_ACT 0x00010000 /* Active */ -#define PAS_DMA_RXCHAN_CCMDSTA_DU 0x00020000 -#define PAS_DMA_RXCHAN_CCMDSTA_OD 0x00002000 -#define PAS_DMA_RXCHAN_CCMDSTA_FD 0x00001000 -#define PAS_DMA_RXCHAN_CCMDSTA_DT 0x00000800 -#define PAS_DMA_RXCHAN_CFG(c) (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_CFG_CTR 0x00000400 -#define PAS_DMA_RXCHAN_CFG_HBU_M 0x00000380 -#define PAS_DMA_RXCHAN_CFG_HBU_S 7 -#define PAS_DMA_RXCHAN_CFG_HBU(x) (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \ - PAS_DMA_RXCHAN_CFG_HBU_M) -#define PAS_DMA_RXCHAN_INCR(c) (0x810+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEL(c) (0x818+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEL_BRBL_M 0xffffffc0 -#define PAS_DMA_RXCHAN_BASEL_BRBL_S 0 -#define PAS_DMA_RXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_RXCHAN_BASEL_BRBL_S) & \ - PAS_DMA_RXCHAN_BASEL_BRBL_M) -#define PAS_DMA_RXCHAN_BASEU(c) (0x81c+(c)*_PAS_DMA_RXCHAN_STRIDE) -#define PAS_DMA_RXCHAN_BASEU_BRBH_M 0x00000fff -#define PAS_DMA_RXCHAN_BASEU_BRBH_S 0 -#define PAS_DMA_RXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_RXCHAN_BASEU_BRBH_S) & \ - PAS_DMA_RXCHAN_BASEU_BRBH_M) -/* # of cache lines worth of buffer ring */ -#define PAS_DMA_RXCHAN_BASEU_SIZ_M 0x3fff0000 -#define PAS_DMA_RXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ -#define PAS_DMA_RXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_RXCHAN_BASEU_SIZ_S) & \ - PAS_DMA_RXCHAN_BASEU_SIZ_M) - -#define PAS_STATUS_PCNT_M 0x000000000000ffffull -#define PAS_STATUS_PCNT_S 0 -#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull -#define PAS_STATUS_DCNT_S 16 -#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull -#define PAS_STATUS_BPCNT_S 32 -#define PAS_STATUS_CAUSE_M 0xf000000000000000ull -#define PAS_STATUS_TIMER 0x1000000000000000ull -#define PAS_STATUS_ERROR 0x2000000000000000ull -#define PAS_STATUS_SOFT 0x4000000000000000ull -#define PAS_STATUS_INT 0x8000000000000000ull - -#define PAS_IOB_COM_PKTHDRCNT 0x120 -#define PAS_IOB_COM_PKTHDRCNT_PKTHDR1_M 0x0fff0000 -#define PAS_IOB_COM_PKTHDRCNT_PKTHDR1_S 16 -#define PAS_IOB_COM_PKTHDRCNT_PKTHDR0_M 0x00000fff -#define PAS_IOB_COM_PKTHDRCNT_PKTHDR0_S 0 - -#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4) -#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff -#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0 -#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \ - PAS_IOB_DMA_RXCH_CFG_CNTTH_M) -#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4) -#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff -#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0 -#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \ - PAS_IOB_DMA_TXCH_CFG_CNTTH_M) -#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4) -#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000 -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0 -#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\ - PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) -#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4) -#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000 -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0 -#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\ - PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) -#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4) -#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16 -#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \ - PAS_IOB_DMA_RXCH_RESET_PCNT_M) -#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020 -#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010 -#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008 -#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004 -#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002 -#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001 -#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4) -#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000 -#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16 -#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \ - PAS_IOB_DMA_TXCH_RESET_PCNT_M) -#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020 -#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010 -#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008 -#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004 -#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002 -#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001 - -#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700 -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0 -#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \ - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M) - -/* Transmit descriptor fields */ -#define XCT_MACTX_T 0x8000000000000000ull -#define XCT_MACTX_ST 0x4000000000000000ull -#define XCT_MACTX_NORES 0x0000000000000000ull -#define XCT_MACTX_8BRES 0x1000000000000000ull -#define XCT_MACTX_24BRES 0x2000000000000000ull -#define XCT_MACTX_40BRES 0x3000000000000000ull -#define XCT_MACTX_I 0x0800000000000000ull -#define XCT_MACTX_O 0x0400000000000000ull -#define XCT_MACTX_E 0x0200000000000000ull -#define XCT_MACTX_VLAN_M 0x0180000000000000ull -#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull -#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull -#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull -#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull -#define XCT_MACTX_CRC_M 0x0060000000000000ull -#define XCT_MACTX_CRC_NOP 0x0000000000000000ull -#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull -#define XCT_MACTX_CRC_PAD 0x0040000000000000ull -#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull -#define XCT_MACTX_SS 0x0010000000000000ull -#define XCT_MACTX_LLEN_M 0x00007fff00000000ull -#define XCT_MACTX_LLEN_S 32ull -#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \ - XCT_MACTX_LLEN_M) -#define XCT_MACTX_IPH_M 0x00000000f8000000ull -#define XCT_MACTX_IPH_S 27ull -#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \ - XCT_MACTX_IPH_M) -#define XCT_MACTX_IPO_M 0x0000000007c00000ull -#define XCT_MACTX_IPO_S 22ull -#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \ - XCT_MACTX_IPO_M) -#define XCT_MACTX_CSUM_M 0x0000000000000060ull -#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull -#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull -#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull -#define XCT_MACTX_V6 0x0000000000000010ull -#define XCT_MACTX_C 0x0000000000000004ull -#define XCT_MACTX_AL2 0x0000000000000002ull - -/* Receive descriptor fields */ -#define XCT_MACRX_T 0x8000000000000000ull -#define XCT_MACRX_ST 0x4000000000000000ull -#define XCT_MACRX_RR_M 0x3000000000000000ull -#define XCT_MACRX_RR_NORES 0x0000000000000000ull -#define XCT_MACRX_RR_8BRES 0x1000000000000000ull -#define XCT_MACRX_O 0x0400000000000000ull -#define XCT_MACRX_E 0x0200000000000000ull -#define XCT_MACRX_FF 0x0100000000000000ull -#define XCT_MACRX_PF 0x0080000000000000ull -#define XCT_MACRX_OB 0x0040000000000000ull -#define XCT_MACRX_OD 0x0020000000000000ull -#define XCT_MACRX_FS 0x0010000000000000ull -#define XCT_MACRX_NB_M 0x000fc00000000000ull -#define XCT_MACRX_NB_S 46ULL -#define XCT_MACRX_NB(x) ((((long)(x)) << XCT_MACRX_NB_S) & \ - XCT_MACRX_NB_M) -#define XCT_MACRX_LLEN_M 0x00003fff00000000ull -#define XCT_MACRX_LLEN_S 32ULL -#define XCT_MACRX_LLEN(x) ((((long)(x)) << XCT_MACRX_LLEN_S) & \ - XCT_MACRX_LLEN_M) -#define XCT_MACRX_CRC 0x0000000080000000ull -#define XCT_MACRX_LEN_M 0x0000000060000000ull -#define XCT_MACRX_LEN_TOOSHORT 0x0000000020000000ull -#define XCT_MACRX_LEN_BELOWMIN 0x0000000040000000ull -#define XCT_MACRX_LEN_TRUNC 0x0000000060000000ull -#define XCT_MACRX_CAST_M 0x0000000018000000ull -#define XCT_MACRX_CAST_UNI 0x0000000000000000ull -#define XCT_MACRX_CAST_MULTI 0x0000000008000000ull -#define XCT_MACRX_CAST_BROAD 0x0000000010000000ull -#define XCT_MACRX_CAST_PAUSE 0x0000000018000000ull -#define XCT_MACRX_VLC_M 0x0000000006000000ull -#define XCT_MACRX_FM 0x0000000001000000ull -#define XCT_MACRX_HTY_M 0x0000000000c00000ull -#define XCT_MACRX_HTY_IPV4_OK 0x0000000000000000ull -#define XCT_MACRX_HTY_IPV6 0x0000000000400000ull -#define XCT_MACRX_HTY_IPV4_BAD 0x0000000000800000ull -#define XCT_MACRX_HTY_NONIP 0x0000000000c00000ull -#define XCT_MACRX_IPP_M 0x00000000003f0000ull -#define XCT_MACRX_IPP_S 16 -#define XCT_MACRX_CSUM_M 0x000000000000ffffull -#define XCT_MACRX_CSUM_S 0 - -#define XCT_PTR_T 0x8000000000000000ull -#define XCT_PTR_LEN_M 0x7ffff00000000000ull -#define XCT_PTR_LEN_S 44 -#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \ - XCT_PTR_LEN_M) -#define XCT_PTR_ADDR_M 0x00000fffffffffffull -#define XCT_PTR_ADDR_S 0 -#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \ - XCT_PTR_ADDR_M) - -/* Receive interface 8byte result fields */ -#define XCT_RXRES_8B_L4O_M 0xff00000000000000ull -#define XCT_RXRES_8B_L4O_S 56 -#define XCT_RXRES_8B_RULE_M 0x00ffff0000000000ull -#define XCT_RXRES_8B_RULE_S 40 -#define XCT_RXRES_8B_EVAL_M 0x000000ffff000000ull -#define XCT_RXRES_8B_EVAL_S 24 -#define XCT_RXRES_8B_HTYPE_M 0x0000000000f00000ull -#define XCT_RXRES_8B_HASH_M 0x00000000000fffffull -#define XCT_RXRES_8B_HASH_S 0 - -/* Receive interface buffer fields */ -#define XCT_RXB_LEN_M 0x0ffff00000000000ull -#define XCT_RXB_LEN_S 44 -#define XCT_RXB_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & XCT_PTR_LEN_M) -#define XCT_RXB_ADDR_M 0x00000fffffffffffull -#define XCT_RXB_ADDR_S 0 -#define XCT_RXB_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & XCT_PTR_ADDR_M) - - #endif /* PASEMI_MAC_H */ diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8d910a3..6d342f6 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -1040,15 +1040,13 @@ void ei_tx_timeout(struct net_device *dev) /* Ugly but a reset can be slow, yet must be protected */ - disable_irq_nosync(dev->irq); - spin_lock(&ei_local->page_lock); + spin_lock_irqsave(&ei_local->page_lock, flags); /* Try to restart the card. Perhaps the user has fixed something. */ ei_reset_8390(dev); AX88190_init(dev, 1); - spin_unlock(&ei_local->page_lock); - enable_irq(dev->irq); + spin_unlock_irqrestore(&ei_local->page_lock, flags); netif_wake_queue(dev); } @@ -1085,9 +1083,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) * Slow phase with lock held. */ - disable_irq_nosync(dev->irq); - - spin_lock(&ei_local->page_lock); + spin_lock_irqsave(&ei_local->page_lock, flags); ei_local->irqlock = 1; @@ -1125,8 +1121,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) ei_local->irqlock = 0; netif_stop_queue(dev); outb_p(ENISR_ALL, e8390_base + EN0_IMR); - spin_unlock(&ei_local->page_lock); - enable_irq(dev->irq); + spin_unlock_irqrestore(&ei_local->page_lock, flags); ei_local->stat.tx_errors++; return 1; } @@ -1172,8 +1167,7 @@ static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev) ei_local->irqlock = 0; outb_p(ENISR_ALL, e8390_base + EN0_IMR); - spin_unlock(&ei_local->page_lock); - enable_irq(dev->irq); + spin_unlock_irqrestore(&ei_local->page_lock, flags); dev_kfree_skb (skb); ei_local->stat.tx_bytes += send_length; diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 8c719b4..949c6df 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -731,18 +731,13 @@ module_exit(exit_fmvj18x_cs); /*====================================================================*/ -static irqreturn_t fjn_interrupt(int irq, void *dev_id) +static irqreturn_t fjn_interrupt(int dummy, void *dev_id) { struct net_device *dev = dev_id; local_info_t *lp = netdev_priv(dev); kio_addr_t ioaddr; unsigned short tx_stat, rx_stat; - if (lp == NULL) { - printk(KERN_NOTICE "fjn_interrupt(): irq %d for " - "unknown device.\n", irq); - return IRQ_NONE; - } ioaddr = dev->base_addr; /* avoid multiple interrupts */ diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index ff92aca..731970a 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -137,7 +137,7 @@ static const char pcnet32_gstrings_test[][ETH_GSTRING_LEN] = { "Loopback test (offline)" }; -#define PCNET32_TEST_LEN (sizeof(pcnet32_gstrings_test) / ETH_GSTRING_LEN) +#define PCNET32_TEST_LEN ARRAY_SIZE(pcnet32_gstrings_test) #define PCNET32_NUM_REGS 136 diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index a7556cd..1b51bb6 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -2489,7 +2489,7 @@ static void __exit pppol2tp_exit(void) module_init(pppol2tp_init); module_exit(pppol2tp_exit); -MODULE_AUTHOR("Martijn van Oosterhout ," +MODULE_AUTHOR("Martijn van Oosterhout , " "James Chapman "); MODULE_DESCRIPTION("PPP over L2TP over UDP"); MODULE_LICENSE("GPL"); diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index a579111..4f5d3d4 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -711,7 +711,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, if (ql_wait_for_mii_ready(qdev)) { if (netif_msg_link(qdev)) printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to" + "%s: Timed out waiting for management port to " "get free before issuing command.\n", qdev->ndev->name); return -1; diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c new file mode 100644 index 0000000..2334f4e --- /dev/null +++ b/drivers/net/r6040.c @@ -0,0 +1,1096 @@ +/* + * RDC R6040 Fast Ethernet MAC support + * + * Copyright (C) 2004 Sten Wang + * Copyright (C) 2007 + * Daniel Gimpelevich + * Florian Fainelli + * + * 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., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#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 DRV_NAME "r6040" +#define DRV_VERSION "0.16" +#define DRV_RELDATE "10Nov2007" + +/* PHY CHIP Address */ +#define PHY1_ADDR 1 /* For MAC1 */ +#define PHY2_ADDR 2 /* For MAC2 */ +#define PHY_MODE 0x3100 /* PHY CHIP Register 0 */ +#define PHY_CAP 0x01E1 /* PHY CHIP Register 4 */ + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (6000 * HZ / 1000) +#define TIMER_WUT (jiffies + HZ * 1)/* timer wakeup time : 1 second */ + +/* RDC MAC I/O Size */ +#define R6040_IO_SIZE 256 + +/* MAX RDC MAC */ +#define MAX_MAC 2 + +/* MAC registers */ +#define MCR0 0x00 /* Control register 0 */ +#define MCR1 0x04 /* Control register 1 */ +#define MAC_RST 0x0001 /* Reset the MAC */ +#define MBCR 0x08 /* Bus control */ +#define MT_ICR 0x0C /* TX interrupt control */ +#define MR_ICR 0x10 /* RX interrupt control */ +#define MTPR 0x14 /* TX poll command register */ +#define MR_BSR 0x18 /* RX buffer size */ +#define MR_DCR 0x1A /* RX descriptor control */ +#define MLSR 0x1C /* Last status */ +#define MMDIO 0x20 /* MDIO control register */ +#define MDIO_WRITE 0x4000 /* MDIO write */ +#define MDIO_READ 0x2000 /* MDIO read */ +#define MMRD 0x24 /* MDIO read data register */ +#define MMWD 0x28 /* MDIO write data register */ +#define MTD_SA0 0x2C /* TX descriptor start address 0 */ +#define MTD_SA1 0x30 /* TX descriptor start address 1 */ +#define MRD_SA0 0x34 /* RX descriptor start address 0 */ +#define MRD_SA1 0x38 /* RX descriptor start address 1 */ +#define MISR 0x3C /* Status register */ +#define MIER 0x40 /* INT enable register */ +#define MSK_INT 0x0000 /* Mask off interrupts */ +#define ME_CISR 0x44 /* Event counter INT status */ +#define ME_CIER 0x48 /* Event counter INT enable */ +#define MR_CNT 0x50 /* Successfully received packet counter */ +#define ME_CNT0 0x52 /* Event counter 0 */ +#define ME_CNT1 0x54 /* Event counter 1 */ +#define ME_CNT2 0x56 /* Event counter 2 */ +#define ME_CNT3 0x58 /* Event counter 3 */ +#define MT_CNT 0x5A /* Successfully transmit packet counter */ +#define ME_CNT4 0x5C /* Event counter 4 */ +#define MP_CNT 0x5E /* Pause frame counter register */ +#define MAR0 0x60 /* Hash table 0 */ +#define MAR1 0x62 /* Hash table 1 */ +#define MAR2 0x64 /* Hash table 2 */ +#define MAR3 0x66 /* Hash table 3 */ +#define MID_0L 0x68 /* Multicast address MID0 Low */ +#define MID_0M 0x6A /* Multicast address MID0 Medium */ +#define MID_0H 0x6C /* Multicast address MID0 High */ +#define MID_1L 0x70 /* MID1 Low */ +#define MID_1M 0x72 /* MID1 Medium */ +#define MID_1H 0x74 /* MID1 High */ +#define MID_2L 0x78 /* MID2 Low */ +#define MID_2M 0x7A /* MID2 Medium */ +#define MID_2H 0x7C /* MID2 High */ +#define MID_3L 0x80 /* MID3 Low */ +#define MID_3M 0x82 /* MID3 Medium */ +#define MID_3H 0x84 /* MID3 High */ +#define PHY_CC 0x88 /* PHY status change configuration register */ +#define PHY_ST 0x8A /* PHY status register */ +#define MAC_SM 0xAC /* MAC status machine */ +#define MAC_ID 0xBE /* Identifier register */ + +#define TX_DCNT 0x80 /* TX descriptor count */ +#define RX_DCNT 0x80 /* RX descriptor count */ +#define MAX_BUF_SIZE 0x600 +#define RX_DESC_SIZE (RX_DCNT * sizeof(struct r6040_descriptor)) +#define TX_DESC_SIZE (TX_DCNT * sizeof(struct r6040_descriptor)) +#define MBCR_DEFAULT 0x012A /* MAC Bus Control Register */ +#define MCAST_MAX 4 /* Max number multicast addresses to filter */ + +/* PHY settings */ +#define ICPLUS_PHY_ID 0x0243 + +MODULE_AUTHOR("Sten Wang ," + "Daniel Gimpelevich ," + "Florian Fainelli "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("RDC R6040 NAPI PCI FastEthernet driver"); + +#define RX_INT 0x0001 +#define TX_INT 0x0010 +#define RX_NO_DESC_INT 0x0002 +#define INT_MASK (RX_INT | TX_INT) + +struct r6040_descriptor { + u16 status, len; /* 0-3 */ + __le32 buf; /* 4-7 */ + __le32 ndesc; /* 8-B */ + u32 rev1; /* C-F */ + char *vbufp; /* 10-13 */ + struct r6040_descriptor *vndescp; /* 14-17 */ + struct sk_buff *skb_ptr; /* 18-1B */ + u32 rev2; /* 1C-1F */ +} __attribute__((aligned(32))); + +struct r6040_private { + spinlock_t lock; /* driver lock */ + struct timer_list timer; + struct pci_dev *pdev; + struct r6040_descriptor *rx_insert_ptr; + struct r6040_descriptor *rx_remove_ptr; + struct r6040_descriptor *tx_insert_ptr; + struct r6040_descriptor *tx_remove_ptr; + struct r6040_descriptor *rx_ring; + struct r6040_descriptor *tx_ring; + dma_addr_t rx_ring_dma; + dma_addr_t tx_ring_dma; + u16 tx_free_desc, rx_free_desc, phy_addr, phy_mode; + u16 mcr0, mcr1; + u16 switch_sig; + struct net_device *dev; + struct mii_if_info mii_if; + struct napi_struct napi; + struct net_device_stats stats; + u16 napi_rx_running; + void __iomem *base; +}; + +static char version[] __devinitdata = KERN_INFO DRV_NAME + ": RDC R6040 NAPI net driver," + "version "DRV_VERSION " (" DRV_RELDATE ")\n"; + +static int phy_table[] = { PHY1_ADDR, PHY2_ADDR }; + +/* Read a word data from PHY Chip */ +static int phy_read(void __iomem *ioaddr, int phy_addr, int reg) +{ + int limit = 2048; + u16 cmd; + + iowrite16(MDIO_READ + reg + (phy_addr << 8), ioaddr + MMDIO); + /* Wait for the read bit to be cleared */ + while (limit--) { + cmd = ioread16(ioaddr + MMDIO); + if (cmd & MDIO_READ) + break; + } + + return ioread16(ioaddr + MMRD); +} + +/* Write a word data from PHY Chip */ +static void phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) +{ + int limit = 2048; + u16 cmd; + + iowrite16(val, ioaddr + MMWD); + /* Write the command to the MDIO bus */ + iowrite16(MDIO_WRITE + reg + (phy_addr << 8), ioaddr + MMDIO); + /* Wait for the write bit to be cleared */ + while (limit--) { + cmd = ioread16(ioaddr + MMDIO); + if (cmd & MDIO_WRITE) + break; + } +} + +static int mdio_read(struct net_device *dev, int mii_id, int reg) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + + return (phy_read(ioaddr, lp->phy_addr, reg)); +} + +static void mdio_write(struct net_device *dev, int mii_id, int reg, int val) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + + phy_write(ioaddr, lp->phy_addr, reg, val); +} + +static void r6040_tx_timeout(struct net_device *dev) +{ + struct r6040_private *priv = netdev_priv(dev); + + disable_irq(dev->irq); + napi_disable(&priv->napi); + spin_lock(&priv->lock); + dev->stats.tx_errors++; + spin_unlock(&priv->lock); + + netif_stop_queue(dev); +} + +/* Allocate skb buffer for rx descriptor */ +static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) +{ + struct r6040_descriptor *descptr; + void __iomem *ioaddr = lp->base; + + descptr = lp->rx_insert_ptr; + while (lp->rx_free_desc < RX_DCNT) { + descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE); + + if (!descptr->skb_ptr) + break; + descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, + descptr->skb_ptr->data, + MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); + descptr->status = 0x8000; + descptr = descptr->vndescp; + lp->rx_free_desc++; + /* Trigger RX DMA */ + iowrite16(lp->mcr0 | 0x0002, ioaddr); + } + lp->rx_insert_ptr = descptr; +} + + +static struct net_device_stats *r6040_get_stats(struct net_device *dev) +{ + struct r6040_private *priv = netdev_priv(dev); + void __iomem *ioaddr = priv->base; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1); + priv->stats.multicast += ioread8(ioaddr + ME_CNT0); + spin_unlock_irqrestore(&priv->lock, flags); + + return &priv->stats; +} + +/* Stop RDC MAC and Free the allocated resource */ +static void r6040_down(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + struct pci_dev *pdev = lp->pdev; + int i; + int limit = 2048; + u16 *adrp; + u16 cmd; + + /* Stop MAC */ + iowrite16(MSK_INT, ioaddr + MIER); /* Mask Off Interrupt */ + iowrite16(MAC_RST, ioaddr + MCR1); /* Reset RDC MAC */ + while (limit--) { + cmd = ioread16(ioaddr + MCR1); + if (cmd & 0x1) + break; + } + + /* Restore MAC Address to MIDx */ + adrp = (u16 *) dev->dev_addr; + iowrite16(adrp[0], ioaddr + MID_0L); + iowrite16(adrp[1], ioaddr + MID_0M); + iowrite16(adrp[2], ioaddr + MID_0H); + free_irq(dev->irq, dev); + /* Free RX buffer */ + for (i = 0; i < RX_DCNT; i++) { + if (lp->rx_insert_ptr->skb_ptr) { + pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, + MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); + dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); + lp->rx_insert_ptr->skb_ptr = NULL; + } + lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp; + } + + /* Free TX buffer */ + for (i = 0; i < TX_DCNT; i++) { + if (lp->tx_insert_ptr->skb_ptr) { + pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, + MAX_BUF_SIZE, PCI_DMA_TODEVICE); + dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); + lp->rx_insert_ptr->skb_ptr = NULL; + } + lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; + } + + /* Free Descriptor memory */ + pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); + pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); +} + +static int r6040_close(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + + /* deleted timer */ + del_timer_sync(&lp->timer); + + spin_lock_irq(&lp->lock); + netif_stop_queue(dev); + r6040_down(dev); + spin_unlock_irq(&lp->lock); + + return 0; +} + +/* Status of PHY CHIP */ +static int phy_mode_chk(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + int phy_dat; + + /* PHY Link Status Check */ + phy_dat = phy_read(ioaddr, lp->phy_addr, 1); + if (!(phy_dat & 0x4)) + phy_dat = 0x8000; /* Link Failed, full duplex */ + + /* PHY Chip Auto-Negotiation Status */ + phy_dat = phy_read(ioaddr, lp->phy_addr, 1); + if (phy_dat & 0x0020) { + /* Auto Negotiation Mode */ + phy_dat = phy_read(ioaddr, lp->phy_addr, 5); + phy_dat &= phy_read(ioaddr, lp->phy_addr, 4); + if (phy_dat & 0x140) + /* Force full duplex */ + phy_dat = 0x8000; + else + phy_dat = 0; + } else { + /* Force Mode */ + phy_dat = phy_read(ioaddr, lp->phy_addr, 0); + if (phy_dat & 0x100) + phy_dat = 0x8000; + else + phy_dat = 0x0000; + } + + return phy_dat; +}; + +static void r6040_set_carrier(struct mii_if_info *mii) +{ + if (phy_mode_chk(mii->dev)) { + /* autoneg is off: Link is always assumed to be up */ + if (!netif_carrier_ok(mii->dev)) + netif_carrier_on(mii->dev); + } else + phy_mode_chk(mii->dev); +} + +static int r6040_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct r6040_private *lp = netdev_priv(dev); + struct mii_ioctl_data *data = if_mii(rq); + int rc; + + if (!netif_running(dev)) + return -EINVAL; + spin_lock_irq(&lp->lock); + rc = generic_mii_ioctl(&lp->mii_if, data, cmd, NULL); + spin_unlock_irq(&lp->lock); + r6040_set_carrier(&lp->mii_if); + return rc; +} + +static int r6040_rx(struct net_device *dev, int limit) +{ + struct r6040_private *priv = netdev_priv(dev); + int count; + void __iomem *ioaddr = priv->base; + u16 err; + + for (count = 0; count < limit; ++count) { + struct r6040_descriptor *descptr = priv->rx_remove_ptr; + struct sk_buff *skb_ptr; + + /* Disable RX interrupt */ + iowrite16(ioread16(ioaddr + MIER) & (~RX_INT), ioaddr + MIER); + descptr = priv->rx_remove_ptr; + + /* Check for errors */ + err = ioread16(ioaddr + MLSR); + if (err & 0x0400) priv->stats.rx_errors++; + /* RX FIFO over-run */ + if (err & 0x8000) priv->stats.rx_fifo_errors++; + /* RX descriptor unavailable */ + if (err & 0x0080) priv->stats.rx_frame_errors++; + /* Received packet with length over buffer lenght */ + if (err & 0x0020) priv->stats.rx_over_errors++; + /* Received packet with too long or short */ + if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++; + /* Received packet with CRC errors */ + if (err & 0x0004) { + spin_lock(&priv->lock); + priv->stats.rx_crc_errors++; + spin_unlock(&priv->lock); + } + + while (priv->rx_free_desc) { + /* No RX packet */ + if (descptr->status & 0x8000) + break; + skb_ptr = descptr->skb_ptr; + if (!skb_ptr) { + printk(KERN_ERR "%s: Inconsistent RX" + "descriptor chain\n", + dev->name); + break; + } + descptr->skb_ptr = NULL; + skb_ptr->dev = priv->dev; + /* Do not count the CRC */ + skb_put(skb_ptr, descptr->len - 4); + pci_unmap_single(priv->pdev, 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->last_rx = jiffies; + priv->dev->stats.rx_packets++; + priv->dev->stats.rx_bytes += descptr->len; + /* To next descriptor */ + descptr = descptr->vndescp; + priv->rx_free_desc--; + } + priv->rx_remove_ptr = descptr; + } + /* Allocate new RX buffer */ + if (priv->rx_free_desc < RX_DCNT) + rx_buf_alloc(priv, priv->dev); + + return count; +} + +static void r6040_tx(struct net_device *dev) +{ + struct r6040_private *priv = netdev_priv(dev); + struct r6040_descriptor *descptr; + void __iomem *ioaddr = priv->base; + struct sk_buff *skb_ptr; + u16 err; + + spin_lock(&priv->lock); + descptr = priv->tx_remove_ptr; + while (priv->tx_free_desc < TX_DCNT) { + /* Check for errors */ + err = ioread16(ioaddr + MLSR); + + if (err & 0x0200) priv->stats.rx_fifo_errors++; + if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++; + + if (descptr->status & 0x8000) + break; /* Not complte */ + skb_ptr = descptr->skb_ptr; + pci_unmap_single(priv->pdev, descptr->buf, + skb_ptr->len, PCI_DMA_TODEVICE); + /* Free buffer */ + dev_kfree_skb_irq(skb_ptr); + descptr->skb_ptr = NULL; + /* To next descriptor */ + descptr = descptr->vndescp; + priv->tx_free_desc++; + } + priv->tx_remove_ptr = descptr; + + if (priv->tx_free_desc) + netif_wake_queue(dev); + spin_unlock(&priv->lock); +} + +static int r6040_poll(struct napi_struct *napi, int budget) +{ + struct r6040_private *priv = + container_of(napi, struct r6040_private, napi); + struct net_device *dev = priv->dev; + void __iomem *ioaddr = priv->base; + int work_done; + + work_done = r6040_rx(dev, budget); + + if (work_done < budget) { + netif_rx_complete(dev, napi); + /* Enable RX interrupt */ + iowrite16(ioread16(ioaddr + MIER) | RX_INT, ioaddr + MIER); + } + return work_done; +} + +/* The RDC interrupt handler. */ +static irqreturn_t r6040_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + u16 status; + int handled = 1; + + /* Mask off RDC MAC interrupt */ + iowrite16(MSK_INT, ioaddr + MIER); + /* Read MISR status and clear */ + status = ioread16(ioaddr + MISR); + + if (status == 0x0000 || status == 0xffff) + return IRQ_NONE; + + /* RX interrupt request */ + if (status & 0x01) { + netif_rx_schedule(dev, &lp->napi); + iowrite16(TX_INT, ioaddr + MIER); + } + + /* TX interrupt request */ + if (status & 0x10) + r6040_tx(dev); + + return IRQ_RETVAL(handled); +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void r6040_poll_controller(struct net_device *dev) +{ + disable_irq(dev->irq); + r6040_interrupt(dev->irq, dev); + enable_irq(dev->irq); +} +#endif + +static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, + dma_addr_t desc_dma, int size) +{ + struct r6040_descriptor *desc = desc_ring; + dma_addr_t mapping = desc_dma; + + while (size-- > 0) { + mapping += sizeof(sizeof(*desc)); + desc->ndesc = cpu_to_le32(mapping); + desc->vndescp = desc + 1; + desc++; + } + desc--; + desc->ndesc = cpu_to_le32(desc_dma); + desc->vndescp = desc_ring; +} + +/* Init RDC MAC */ +static void r6040_up(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + + /* Initialize */ + lp->tx_free_desc = TX_DCNT; + lp->rx_free_desc = 0; + /* Init descriptor */ + lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; + lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; + /* Init TX descriptor */ + r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); + + /* Init RX descriptor */ + r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); + + /* Allocate buffer for RX descriptor */ + rx_buf_alloc(lp, dev); + + /* + * TX and RX descriptor start registers. + * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1. + */ + iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); + iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); + + iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); + iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); + + /* Buffer Size Register */ + iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); + /* Read the PHY ID */ + lp->switch_sig = phy_read(ioaddr, 0, 2); + + if (lp->switch_sig == ICPLUS_PHY_ID) { + phy_write(ioaddr, 29, 31, 0x175C); /* Enable registers */ + lp->phy_mode = 0x8000; + } else { + /* PHY Mode Check */ + phy_write(ioaddr, lp->phy_addr, 4, PHY_CAP); + phy_write(ioaddr, lp->phy_addr, 0, PHY_MODE); + + if (PHY_MODE == 0x3100) + lp->phy_mode = phy_mode_chk(dev); + else + lp->phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; + } + /* MAC Bus Control Register */ + iowrite16(MBCR_DEFAULT, ioaddr + MBCR); + + /* MAC TX/RX Enable */ + lp->mcr0 |= lp->phy_mode; + iowrite16(lp->mcr0, ioaddr); + + /* set interrupt waiting time and packet numbers */ + iowrite16(0x0F06, ioaddr + MT_ICR); + iowrite16(0x0F06, ioaddr + MR_ICR); + + /* improve performance (by RDC guys) */ + phy_write(ioaddr, 30, 17, (phy_read(ioaddr, 30, 17) | 0x4000)); + phy_write(ioaddr, 30, 17, ~((~phy_read(ioaddr, 30, 17)) | 0x2000)); + phy_write(ioaddr, 0, 19, 0x0000); + phy_write(ioaddr, 0, 30, 0x01F0); + + /* Interrupt Mask Register */ + iowrite16(INT_MASK, ioaddr + MIER); +} + +/* + A periodic timer routine + Polling PHY Chip Link Status +*/ +static void r6040_timer(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + u16 phy_mode; + + /* Polling PHY Chip Status */ + if (PHY_MODE == 0x3100) + phy_mode = phy_mode_chk(dev); + else + phy_mode = (PHY_MODE & 0x0100) ? 0x8000:0x0; + + if (phy_mode != lp->phy_mode) { + lp->phy_mode = phy_mode; + lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode; + iowrite16(lp->mcr0, ioaddr); + printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr)); + } + + /* Timer active again */ + lp->timer.expires = TIMER_WUT; + add_timer(&lp->timer); +} + +/* Read/set MAC address routines */ +static void r6040_mac_address(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + u16 *adrp; + + /* MAC operation register */ + iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */ + iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */ + iowrite16(0, ioaddr + MAC_SM); + udelay(5000); + + /* Restore MAC Address */ + adrp = (u16 *) dev->dev_addr; + iowrite16(adrp[0], ioaddr + MID_0L); + iowrite16(adrp[1], ioaddr + MID_0M); + iowrite16(adrp[2], ioaddr + MID_0H); +} + +static int r6040_open(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + int ret; + + /* Request IRQ and Register interrupt handler */ + ret = request_irq(dev->irq, &r6040_interrupt, + IRQF_SHARED, dev->name, dev); + if (ret) + return ret; + + /* Set MAC address */ + r6040_mac_address(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; + + 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; + } + + r6040_up(dev); + + napi_enable(&lp->napi); + netif_start_queue(dev); + + if (lp->switch_sig != ICPLUS_PHY_ID) { + /* set and active a timer process */ + init_timer(&lp->timer); + lp->timer.expires = TIMER_WUT; + lp->timer.data = (unsigned long)dev; + lp->timer.function = &r6040_timer; + add_timer(&lp->timer); + } + return 0; +} + +static int r6040_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + struct r6040_descriptor *descptr; + void __iomem *ioaddr = lp->base; + unsigned long flags; + int ret = NETDEV_TX_OK; + + /* Critical Section */ + spin_lock_irqsave(&lp->lock, flags); + + /* TX resource check */ + if (!lp->tx_free_desc) { + spin_unlock_irqrestore(&lp->lock, flags); + netif_stop_queue(dev); + printk(KERN_ERR DRV_NAME ": no tx descriptor\n"); + ret = NETDEV_TX_BUSY; + return ret; + } + + /* Statistic Counter */ + dev->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + /* Set TX descriptor & Transmit it */ + lp->tx_free_desc--; + descptr = lp->tx_insert_ptr; + if (skb->len < MISR) + descptr->len = MISR; + else + descptr->len = skb->len; + + descptr->skb_ptr = skb; + descptr->buf = cpu_to_le32(pci_map_single(lp->pdev, + skb->data, skb->len, PCI_DMA_TODEVICE)); + descptr->status = 0x8000; + /* Trigger the MAC to check the TX descriptor */ + iowrite16(0x01, ioaddr + MTPR); + lp->tx_insert_ptr = descptr->vndescp; + + /* If no tx resource, stop */ + if (!lp->tx_free_desc) + netif_stop_queue(dev); + + dev->trans_start = jiffies; + spin_unlock_irqrestore(&lp->lock, flags); + return ret; +} + +static void r6040_multicast_list(struct net_device *dev) +{ + struct r6040_private *lp = netdev_priv(dev); + void __iomem *ioaddr = lp->base; + u16 *adrp; + u16 reg; + unsigned long flags; + struct dev_mc_list *dmi = dev->mc_list; + int i; + + /* MAC Address */ + adrp = (u16 *)dev->dev_addr; + iowrite16(adrp[0], ioaddr + MID_0L); + iowrite16(adrp[1], ioaddr + MID_0M); + iowrite16(adrp[2], ioaddr + MID_0H); + + /* Promiscous Mode */ + spin_lock_irqsave(&lp->lock, flags); + + /* Clear AMCP & PROM bits */ + reg = ioread16(ioaddr) & ~0x0120; + if (dev->flags & IFF_PROMISC) { + reg |= 0x0020; + lp->mcr0 |= 0x0020; + } + /* Too many multicast addresses + * accept all traffic */ + else if ((dev->mc_count > MCAST_MAX) + || (dev->flags & IFF_ALLMULTI)) + reg |= 0x0020; + + iowrite16(reg, ioaddr); + spin_unlock_irqrestore(&lp->lock, flags); + + /* Build the hash table */ + if (dev->mc_count > MCAST_MAX) { + u16 hash_table[4]; + u32 crc; + + for (i = 0; i < 4; i++) + hash_table[i] = 0; + + for (i = 0; i < dev->mc_count; i++) { + char *addrs = dmi->dmi_addr; + + dmi = dmi->next; + + if (!(*addrs & 1)) + continue; + + crc = ether_crc_le(6, addrs); + crc >>= 26; + hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf)); + } + /* Write the index of the hash table */ + for (i = 0; i < 4; i++) + iowrite16(hash_table[i] << 14, ioaddr + MCR1); + /* Fill the MAC hash tables with their values */ + iowrite16(hash_table[0], ioaddr + MAR0); + iowrite16(hash_table[1], ioaddr + MAR1); + iowrite16(hash_table[2], ioaddr + MAR2); + iowrite16(hash_table[3], ioaddr + MAR3); + } + /* Multicast Address 1~4 case */ + for (i = 0, dmi; (i < dev->mc_count) && (i < MCAST_MAX); i++) { + adrp = (u16 *)dmi->dmi_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); + dmi = dmi->next; + } + for (i = dev->mc_count; i < MCAST_MAX; i++) { + iowrite16(0xffff, ioaddr + MID_0L + 8*i); + iowrite16(0xffff, ioaddr + MID_0M + 8*i); + iowrite16(0xffff, ioaddr + MID_0H + 8*i); + } +} + +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct r6040_private *rp = netdev_priv(dev); + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(rp->pdev)); +} + +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct r6040_private *rp = netdev_priv(dev); + int rc; + + spin_lock_irq(&rp->lock); + rc = mii_ethtool_gset(&rp->mii_if, cmd); + spin_unlock_irq(&rp->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct r6040_private *rp = netdev_priv(dev); + int rc; + + spin_lock_irq(&rp->lock); + rc = mii_ethtool_sset(&rp->mii_if, cmd); + spin_unlock_irq(&rp->lock); + r6040_set_carrier(&rp->mii_if); + + return rc; +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct r6040_private *rp = netdev_priv(dev); + + return mii_link_ok(&rp->mii_if); +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .get_link = netdev_get_link, +}; + +static int __devinit r6040_init_one(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct net_device *dev; + struct r6040_private *lp; + void __iomem *ioaddr; + int err, io_size = R6040_IO_SIZE; + static int card_idx = -1; + int bar = 0; + long pioaddr; + u16 *adrp; + + printk(KERN_INFO "%s\n", version); + + err = pci_enable_device(pdev); + if (err) + return err; + + /* this should always be supported */ + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { + printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" + "not supported by the card\n"); + return -ENODEV; + } + if (pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { + printk(KERN_ERR DRV_NAME "32-bit PCI DMA addresses" + "not supported by the card\n"); + return -ENODEV; + } + + /* IO Size check */ + if (pci_resource_len(pdev, 0) < io_size) { + printk(KERN_ERR "Insufficient PCI resources, aborting\n"); + return -EIO; + } + + pioaddr = pci_resource_start(pdev, 0); /* IO map base address */ + pci_set_master(pdev); + + dev = alloc_etherdev(sizeof(struct r6040_private)); + if (!dev) { + printk(KERN_ERR "Failed to allocate etherdev\n"); + return -ENOMEM; + } + SET_NETDEV_DEV(dev, &pdev->dev); + lp = netdev_priv(dev); + lp->pdev = pdev; + + if (pci_request_regions(pdev, DRV_NAME)) { + printk(KERN_ERR DRV_NAME ": Failed to request PCI regions\n"); + err = -ENODEV; + goto err_out_disable; + } + + ioaddr = pci_iomap(pdev, bar, io_size); + if (!ioaddr) { + printk(KERN_ERR "ioremap failed for device %s\n", + pci_name(pdev)); + return -EIO; + } + + /* Init system & device */ + lp->base = ioaddr; + dev->irq = pdev->irq; + + spin_lock_init(&lp->lock); + pci_set_drvdata(pdev, dev); + + /* Set MAC address */ + card_idx++; + + adrp = (u16 *)dev->dev_addr; + adrp[0] = ioread16(ioaddr + MID_0L); + adrp[1] = ioread16(ioaddr + MID_0M); + adrp[2] = ioread16(ioaddr + MID_0H); + + /* Link new device into r6040_root_dev */ + lp->pdev = pdev; + + /* Init RDC private data */ + lp->mcr0 = 0x1002; + lp->phy_addr = phy_table[card_idx]; + lp->switch_sig = 0; + + /* The RDC-specific entries in the device structure. */ + dev->open = &r6040_open; + dev->hard_start_xmit = &r6040_start_xmit; + dev->stop = &r6040_close; + dev->get_stats = r6040_get_stats; + dev->set_multicast_list = &r6040_multicast_list; + dev->do_ioctl = &r6040_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; + dev->tx_timeout = &r6040_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = r6040_poll_controller; +#endif + netif_napi_add(dev, &lp->napi, r6040_poll, 64); + lp->mii_if.dev = dev; + lp->mii_if.mdio_read = mdio_read; + lp->mii_if.mdio_write = mdio_write; + lp->mii_if.phy_id = lp->phy_addr; + lp->mii_if.phy_id_mask = 0x1f; + lp->mii_if.reg_num_mask = 0x1f; + + /* Register net device. After this dev->name assign */ + err = register_netdev(dev); + if (err) { + printk(KERN_ERR DRV_NAME ": Failed to register net device\n"); + goto err_out_res; + } + return 0; + +err_out_res: + pci_release_regions(pdev); +err_out_disable: + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + free_netdev(dev); + + return err; +} + +static void __devexit r6040_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + + unregister_netdev(dev); + pci_release_regions(pdev); + free_netdev(dev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + + +static struct pci_device_id r6040_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_RDC, 0x6040) }, + { 0 } +}; +MODULE_DEVICE_TABLE(pci, r6040_pci_tbl); + +static struct pci_driver r6040_driver = { + .name = DRV_NAME, + .id_table = r6040_pci_tbl, + .probe = r6040_init_one, + .remove = __devexit_p(r6040_remove_one), +}; + + +static int __init r6040_init(void) +{ + return pci_register_driver(&r6040_driver); +} + + +static void __exit r6040_cleanup(void) +{ + pci_unregister_driver(&r6040_driver); +} + +module_init(r6040_init); +module_exit(r6040_cleanup); diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index 73a7e65..379ded5 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -878,7 +878,7 @@ static u32 rr_handle_event(struct net_device *dev, u32 prodidx, u32 eidx) dev->name); goto drop; case E_FLG_SYN_ERR: - printk(KERN_WARNING "%s: Flag sync. lost during" + printk(KERN_WARNING "%s: Flag sync. lost during " "packet\n", dev->name); goto drop; case E_RX_INV_BUF: diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index f25264f..2109508 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h @@ -723,11 +723,17 @@ struct XENA_dev_config { u64 rmac_cfg_key; #define RMAC_CFG_KEY(val) vBIT(val,0,16) -#define MAX_MAC_ADDRESSES 16 -#define MAX_MC_ADDRESSES 32 /* Multicast addresses */ -#define MAC_MAC_ADDR_START_OFFSET 0 -#define MAC_MC_ADDR_START_OFFSET 16 -#define MAC_MC_ALL_MC_ADDR_OFFSET 63 /* enables all multicast pkts */ +#define S2IO_MAC_ADDR_START_OFFSET 0 + +#define S2IO_XENA_MAX_MC_ADDRESSES 64 /* multicast addresses */ +#define S2IO_HERC_MAX_MC_ADDRESSES 256 + +#define S2IO_XENA_MAX_MAC_ADDRESSES 16 +#define S2IO_HERC_MAX_MAC_ADDRESSES 64 + +#define S2IO_XENA_MC_ADDR_START_OFFSET 16 +#define S2IO_HERC_MC_ADDR_START_OFFSET 64 + u64 rmac_addr_cmd_mem; #define RMAC_ADDR_CMD_MEM_WE s2BIT(7) #define RMAC_ADDR_CMD_MEM_RD 0 diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 121cb10..4256157 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -335,10 +335,9 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { {"mc_err_cnt"} }; -#define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN -#define S2IO_ENHANCED_STAT_LEN sizeof(ethtool_enhanced_stats_keys)/ \ - ETH_GSTRING_LEN -#define S2IO_DRIVER_STAT_LEN sizeof(ethtool_driver_stats_keys)/ ETH_GSTRING_LEN +#define S2IO_XENA_STAT_LEN ARRAY_SIZE(ethtool_xena_stats_keys) +#define S2IO_ENHANCED_STAT_LEN ARRAY_SIZE(ethtool_enhanced_stats_keys) +#define S2IO_DRIVER_STAT_LEN ARRAY_SIZE(ethtool_driver_stats_keys) #define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN ) #define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN ) @@ -346,7 +345,7 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { #define XFRAME_I_STAT_STRINGS_LEN ( XFRAME_I_STAT_LEN * ETH_GSTRING_LEN ) #define XFRAME_II_STAT_STRINGS_LEN ( XFRAME_II_STAT_LEN * ETH_GSTRING_LEN ) -#define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN +#define S2IO_TEST_LEN ARRAY_SIZE(s2io_gstrings) #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN #define S2IO_TIMER_CONF(timer, handle, arg, exp) \ @@ -3379,6 +3378,9 @@ static void s2io_reset(struct s2io_nic * sp) /* Set swapper to enable I/O register access */ s2io_set_swapper(sp); + /* restore mac_addr entries */ + do_s2io_restore_unicast_mc(sp); + /* Restore the MSIX table entries from local variables */ restore_xmsi_data(sp); @@ -3437,9 +3439,6 @@ static void s2io_reset(struct s2io_nic * sp) writeq(val64, &bar0->pcc_err_reg); } - /* restore the previously assigned mac address */ - do_s2io_prog_unicast(sp->dev, (u8 *)&sp->def_mac_addr[0].mac_addr); - sp->device_enabled_once = FALSE; } @@ -3776,7 +3775,7 @@ static int __devinit s2io_test_msi(struct s2io_nic *sp) if (!sp->msi_detected) { /* MSI(X) test failed, go back to INTx mode */ - DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated" + DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated " "using MSI(X) during test\n", sp->dev->name, pci_name(pdev)); @@ -3927,6 +3926,9 @@ hw_init_failed: static int s2io_close(struct net_device *dev) { struct s2io_nic *sp = dev->priv; + struct config_param *config = &sp->config; + u64 tmp64; + int offset; /* Return if the device is already closed * * Can happen when s2io_card_up failed in change_mtu * @@ -3935,6 +3937,14 @@ static int s2io_close(struct net_device *dev) return 0; netif_stop_queue(dev); + + /* delete all populated mac entries */ + for (offset = 1; offset < config->max_mc_addr; offset++) { + tmp64 = do_s2io_read_unicast_mc(sp, offset); + if (tmp64 != S2IO_DISABLE_MAC_ENTRY) + do_s2io_delete_unicast_mc(sp, tmp64); + } + napi_disable(&sp->napi); /* Reset card, kill tasklet and free Tx and Rx buffers. */ s2io_card_down(sp); @@ -4736,8 +4746,9 @@ static void s2io_set_multicast(struct net_device *dev) struct XENA_dev_config __iomem *bar0 = sp->bar0; u64 val64 = 0, multi_mac = 0x010203040506ULL, mask = 0xfeffffffffffULL; - u64 dis_addr = 0xffffffffffffULL, mac_addr = 0; + u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, mac_addr = 0; void __iomem *add; + struct config_param *config = &sp->config; if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) { /* Enable all Multicast addresses */ @@ -4747,7 +4758,7 @@ static void s2io_set_multicast(struct net_device *dev) &bar0->rmac_addr_data1_mem); val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | - RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); + RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait till command completes */ wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, @@ -4755,7 +4766,7 @@ static void s2io_set_multicast(struct net_device *dev) S2IO_BIT_RESET); sp->m_cast_flg = 1; - sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; + sp->all_multi_pos = config->max_mc_addr - 1; } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) { /* Disable all Multicast addresses */ writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), @@ -4824,7 +4835,7 @@ static void s2io_set_multicast(struct net_device *dev) /* Update individual M_CAST address list */ if ((!sp->m_cast_flg) && dev->mc_count) { if (dev->mc_count > - (MAX_ADDRS_SUPPORTED - MAC_MC_ADDR_START_OFFSET - 1)) { + (config->max_mc_addr - config->max_mac_addr)) { DBG_PRINT(ERR_DBG, "%s: No more Rx filters ", dev->name); DBG_PRINT(ERR_DBG, "can be added, please enable "); @@ -4844,7 +4855,7 @@ static void s2io_set_multicast(struct net_device *dev) val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET - (MAC_MC_ADDR_START_OFFSET + i); + (config->mc_start_offset + i); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ @@ -4876,7 +4887,7 @@ static void s2io_set_multicast(struct net_device *dev) val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | RMAC_ADDR_CMD_MEM_OFFSET - (i + MAC_MC_ADDR_START_OFFSET); + (i + config->mc_start_offset); writeq(val64, &bar0->rmac_addr_cmd_mem); /* Wait for command completes */ @@ -4892,8 +4903,78 @@ static void s2io_set_multicast(struct net_device *dev) } } -/* add unicast MAC address to CAM */ -static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off) +/* read from CAM unicast & multicast addresses and store it in + * def_mac_addr structure + */ +void do_s2io_store_unicast_mc(struct s2io_nic *sp) +{ + int offset; + u64 mac_addr = 0x0; + struct config_param *config = &sp->config; + + /* store unicast & multicast mac addresses */ + for (offset = 0; offset < config->max_mc_addr; offset++) { + mac_addr = do_s2io_read_unicast_mc(sp, offset); + /* if read fails disable the entry */ + if (mac_addr == FAILURE) + mac_addr = S2IO_DISABLE_MAC_ENTRY; + do_s2io_copy_mac_addr(sp, offset, mac_addr); + } +} + +/* restore unicast & multicast MAC to CAM from def_mac_addr structure */ +static void do_s2io_restore_unicast_mc(struct s2io_nic *sp) +{ + int offset; + struct config_param *config = &sp->config; + /* restore unicast mac address */ + for (offset = 0; offset < config->max_mac_addr; offset++) + do_s2io_prog_unicast(sp->dev, + sp->def_mac_addr[offset].mac_addr); + + /* restore multicast mac address */ + for (offset = config->mc_start_offset; + offset < config->max_mc_addr; offset++) + do_s2io_add_mc(sp, sp->def_mac_addr[offset].mac_addr); +} + +/* add a multicast MAC address to CAM */ +static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr) +{ + int i; + u64 mac_addr = 0; + struct config_param *config = &sp->config; + + for (i = 0; i < ETH_ALEN; i++) { + mac_addr <<= 8; + mac_addr |= addr[i]; + } + if ((0ULL == mac_addr) || (mac_addr == S2IO_DISABLE_MAC_ENTRY)) + return SUCCESS; + + /* check if the multicast mac already preset in CAM */ + for (i = config->mc_start_offset; i < config->max_mc_addr; i++) { + u64 tmp64; + tmp64 = do_s2io_read_unicast_mc(sp, i); + if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */ + break; + + if (tmp64 == mac_addr) + return SUCCESS; + } + if (i == config->max_mc_addr) { + DBG_PRINT(ERR_DBG, + "CAM full no space left for multicast MAC\n"); + return FAILURE; + } + /* Update the internal structure with this new mac address */ + do_s2io_copy_mac_addr(sp, i, mac_addr); + + return (do_s2io_add_mac(sp, mac_addr, i)); +} + +/* add MAC address to CAM */ +static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off) { u64 val64; struct XENA_dev_config __iomem *bar0 = sp->bar0; @@ -4910,15 +4991,62 @@ static int do_s2io_add_unicast(struct s2io_nic *sp, u64 addr, int off) if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET)) { - DBG_PRINT(INFO_DBG, "add_mac_addr failed\n"); + DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n"); return FAILURE; } return SUCCESS; } +/* deletes a specified unicast/multicast mac entry from CAM */ +static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr) +{ + int offset; + u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, tmp64; + struct config_param *config = &sp->config; + + for (offset = 1; + offset < config->max_mc_addr; offset++) { + tmp64 = do_s2io_read_unicast_mc(sp, offset); + if (tmp64 == addr) { + /* disable the entry by writing 0xffffffffffffULL */ + if (do_s2io_add_mac(sp, dis_addr, offset) == FAILURE) + return FAILURE; + /* store the new mac list from CAM */ + do_s2io_store_unicast_mc(sp); + return SUCCESS; + } + } + DBG_PRINT(ERR_DBG, "MAC address 0x%llx not found in CAM\n", + (unsigned long long)addr); + return FAILURE; +} + +/* read mac entries from CAM */ +static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset) +{ + u64 tmp64 = 0xffffffffffff0000ULL, val64; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + + /* read mac addr */ + val64 = + RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | + RMAC_ADDR_CMD_MEM_OFFSET(offset); + writeq(val64, &bar0->rmac_addr_cmd_mem); + + /* Wait till command completes */ + if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, + RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, + S2IO_BIT_RESET)) { + DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n"); + return FAILURE; + } + tmp64 = readq(&bar0->rmac_addr_data0_mem); + return (tmp64 >> 16); +} /** * s2io_set_mac_addr driver entry point */ + static int s2io_set_mac_addr(struct net_device *dev, void *p) { struct sockaddr *addr = p; @@ -4931,7 +5059,6 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p) /* store the MAC address in CAM */ return (do_s2io_prog_unicast(dev, dev->dev_addr)); } - /** * do_s2io_prog_unicast - Programs the Xframe mac address * @dev : pointer to the device structure. @@ -4941,11 +5068,14 @@ static int s2io_set_mac_addr(struct net_device *dev, void *p) * Return value: SUCCESS on success and an appropriate (-)ve integer * as defined in errno.h file on failure. */ + static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr) { struct s2io_nic *sp = dev->priv; register u64 mac_addr = 0, perm_addr = 0; int i; + u64 tmp64; + struct config_param *config = &sp->config; /* * Set the new MAC address as the new unicast filter and reflect this @@ -4963,9 +5093,26 @@ static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr) if (mac_addr == perm_addr) return SUCCESS; + /* check if the mac already preset in CAM */ + for (i = 1; i < config->max_mac_addr; i++) { + tmp64 = do_s2io_read_unicast_mc(sp, i); + if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */ + break; + + if (tmp64 == mac_addr) { + DBG_PRINT(INFO_DBG, + "MAC addr:0x%llx already present in CAM\n", + (unsigned long long)mac_addr); + return SUCCESS; + } + } + if (i == config->max_mac_addr) { + DBG_PRINT(ERR_DBG, "CAM full no space left for Unicast MAC\n"); + return FAILURE; + } /* Update the internal structure with this new mac address */ - do_s2io_copy_mac_addr(sp, 0, mac_addr); - return (do_s2io_add_unicast(sp, mac_addr, 0)); + do_s2io_copy_mac_addr(sp, i, mac_addr); + return (do_s2io_add_mac(sp, mac_addr, i)); } /** @@ -6728,7 +6875,7 @@ static int s2io_add_isr(struct s2io_nic * sp) /* If either data or addr is zero print it */ if(!(sp->msix_info[i].addr && sp->msix_info[i].data)) { - DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx" + DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " "Data:0x%lx\n",sp->desc[i], (unsigned long long) sp->msix_info[i].addr, @@ -6746,7 +6893,7 @@ static int s2io_add_isr(struct s2io_nic * sp) /* If either data or addr is zero print it */ if(!(sp->msix_info[i].addr && sp->msix_info[i].data)) { - DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx" + DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " "Data:0x%lx\n",sp->desc[i], (unsigned long long) sp->msix_info[i].addr, @@ -7648,7 +7795,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) */ bar0 = sp->bar0; val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | - RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); + RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET); writeq(val64, &bar0->rmac_addr_cmd_mem); wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING, S2IO_BIT_RESET); @@ -7668,6 +7815,20 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); + /* initialize number of multicast & unicast MAC entries variables */ + if (sp->device_type == XFRAME_I_DEVICE) { + config->max_mc_addr = S2IO_XENA_MAX_MC_ADDRESSES; + config->max_mac_addr = S2IO_XENA_MAX_MAC_ADDRESSES; + config->mc_start_offset = S2IO_XENA_MC_ADDR_START_OFFSET; + } else if (sp->device_type == XFRAME_II_DEVICE) { + config->max_mc_addr = S2IO_HERC_MAX_MC_ADDRESSES; + config->max_mac_addr = S2IO_HERC_MAX_MAC_ADDRESSES; + config->mc_start_offset = S2IO_HERC_MC_ADDR_START_OFFSET; + } + + /* store mac addresses from CAM to s2io_nic structure */ + do_s2io_store_unicast_mc(sp); + /* Store the values of the MSIX table in the s2io_nic structure */ store_xmsi_data(sp); /* reset Nic and bring it to known state */ diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index cc1797a..b944a94 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -31,6 +31,7 @@ #define SUCCESS 0 #define FAILURE -1 #define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL +#define S2IO_DISABLE_MAC_ENTRY 0xFFFFFFFFFFFFULL #define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100 #define S2IO_BIT_RESET 1 #define S2IO_BIT_SET 2 @@ -458,6 +459,9 @@ struct config_param { #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) u16 bus_speed; + int max_mc_addr; /* xena=64 herc=256 */ + int max_mac_addr; /* xena=16 herc=64 */ + int mc_start_offset; /* xena=16 herc=64 */ }; /* Structure representing MAC Addrs */ @@ -826,7 +830,7 @@ struct s2io_nic { #define MAX_MAC_SUPPORTED 16 #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED - struct mac_addr def_mac_addr[MAX_MAC_SUPPORTED]; + struct mac_addr def_mac_addr[256]; struct net_device_stats stats; int high_dma_flag; @@ -853,7 +857,7 @@ struct s2io_nic { #define MAX_ADDRS_SUPPORTED 64 u16 usr_addr_count; u16 mc_addr_count; - struct usr_addr usr_addrs[MAX_ADDRS_SUPPORTED]; + struct usr_addr usr_addrs[256]; u16 m_cast_flg; u16 all_multi_pos; @@ -1066,6 +1070,12 @@ static int s2io_add_isr(struct s2io_nic * sp); static void s2io_rem_isr(struct s2io_nic * sp); static void restore_xmsi_data(struct s2io_nic *nic); +static void do_s2io_store_unicast_mc(struct s2io_nic *sp); +static void do_s2io_restore_unicast_mc(struct s2io_nic *sp); +static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset); +static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr); +static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset); +static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr); static int s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index ff40563..3145ca1 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -53,14 +52,35 @@ static char *sgiseeqstr = "SGI Seeq8003"; sp->tx_old + (SEEQ_TX_BUFFERS - 1) - sp->tx_new : \ sp->tx_old - sp->tx_new - 1) +#define VIRT_TO_DMA(sp, v) ((sp)->srings_dma + \ + (dma_addr_t)((unsigned long)(v) - \ + (unsigned long)((sp)->rx_desc))) + +#define DMA_SYNC_DESC_CPU(dev, addr) \ + do { dma_cache_sync((dev)->dev.parent, (void *)addr, \ + sizeof(struct sgiseeq_rx_desc), DMA_FROM_DEVICE); } while (0) + +#define DMA_SYNC_DESC_DEV(dev, addr) \ + do { dma_cache_sync((dev)->dev.parent, (void *)addr, \ + sizeof(struct sgiseeq_rx_desc), DMA_TO_DEVICE); } while (0) + +/* Copy frames shorter than rx_copybreak, otherwise pass on up in + * a full sized sk_buff. Value of 100 stolen from tulip.c (!alpha). + */ +static int rx_copybreak = 100; + +#define PAD_SIZE (128 - sizeof(struct hpc_dma_desc) - sizeof(void *)) + struct sgiseeq_rx_desc { volatile struct hpc_dma_desc rdma; - volatile signed int buf_vaddr; + u8 padding[PAD_SIZE]; + struct sk_buff *skb; }; struct sgiseeq_tx_desc { volatile struct hpc_dma_desc tdma; - volatile signed int buf_vaddr; + u8 padding[PAD_SIZE]; + struct sk_buff *skb; }; /* @@ -163,35 +183,55 @@ static int seeq_init_ring(struct net_device *dev) /* Setup tx ring. */ for(i = 0; i < SEEQ_TX_BUFFERS; i++) { - if (!sp->tx_desc[i].tdma.pbuf) { - unsigned long buffer; - - buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer); - sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer); - } sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT; + DMA_SYNC_DESC_DEV(dev, &sp->tx_desc[i]); } /* And now the rx ring. */ for (i = 0; i < SEEQ_RX_BUFFERS; i++) { if (!sp->rx_desc[i].rdma.pbuf) { - unsigned long buffer; + dma_addr_t dma_addr; + struct sk_buff *skb = netdev_alloc_skb(dev, PKT_BUF_SZ); - buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL); - if (!buffer) + if (skb == NULL) return -ENOMEM; - sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer); - sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer); + skb_reserve(skb, 2); + dma_addr = dma_map_single(dev->dev.parent, + skb->data - 2, + PKT_BUF_SZ, DMA_FROM_DEVICE); + sp->rx_desc[i].skb = skb; + sp->rx_desc[i].rdma.pbuf = dma_addr; } sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT; + DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[i]); } sp->rx_desc[i - 1].rdma.cntinfo |= HPCDMA_EOR; + DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[i - 1]); return 0; } +static void seeq_purge_ring(struct net_device *dev) +{ + struct sgiseeq_private *sp = netdev_priv(dev); + int i; + + /* clear tx ring. */ + for (i = 0; i < SEEQ_TX_BUFFERS; i++) { + if (sp->tx_desc[i].skb) { + dev_kfree_skb(sp->tx_desc[i].skb); + sp->tx_desc[i].skb = NULL; + } + } + + /* And now the rx ring. */ + for (i = 0; i < SEEQ_RX_BUFFERS; i++) { + if (sp->rx_desc[i].skb) { + dev_kfree_skb(sp->rx_desc[i].skb); + sp->rx_desc[i].skb = NULL; + } + } +} + #ifdef DEBUG static struct sgiseeq_private *gpriv; static struct net_device *gdev; @@ -258,8 +298,8 @@ static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp, sregs->tstat = TSTAT_INIT_SEEQ; } - hregs->rx_ndptr = CPHYSADDR(sp->rx_desc); - hregs->tx_ndptr = CPHYSADDR(sp->tx_desc); + hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc); + hregs->tx_ndptr = VIRT_TO_DMA(sp, sp->tx_desc); seeq_go(sp, hregs, sregs); return 0; @@ -283,69 +323,90 @@ static inline void rx_maybe_restart(struct sgiseeq_private *sp, struct sgiseeq_regs *sregs) { if (!(hregs->rx_ctrl & HPC3_ERXCTRL_ACTIVE)) { - hregs->rx_ndptr = CPHYSADDR(sp->rx_desc + sp->rx_new); + hregs->rx_ndptr = VIRT_TO_DMA(sp, sp->rx_desc + sp->rx_new); seeq_go(sp, hregs, sregs); } } -#define for_each_rx(rd, sp) for((rd) = &(sp)->rx_desc[(sp)->rx_new]; \ - !((rd)->rdma.cntinfo & HPCDMA_OWN); \ - (rd) = &(sp)->rx_desc[(sp)->rx_new]) - static inline void sgiseeq_rx(struct net_device *dev, struct sgiseeq_private *sp, struct hpc3_ethregs *hregs, struct sgiseeq_regs *sregs) { struct sgiseeq_rx_desc *rd; struct sk_buff *skb = NULL; + struct sk_buff *newskb; unsigned char pkt_status; - unsigned char *pkt_pointer = NULL; int len = 0; unsigned int orig_end = PREV_RX(sp->rx_new); /* Service every received packet. */ - for_each_rx(rd, sp) { + rd = &sp->rx_desc[sp->rx_new]; + DMA_SYNC_DESC_CPU(dev, rd); + while (!(rd->rdma.cntinfo & HPCDMA_OWN)) { len = PKT_BUF_SZ - (rd->rdma.cntinfo & HPCDMA_BCNT) - 3; - pkt_pointer = (unsigned char *)(long)rd->buf_vaddr; - pkt_status = pkt_pointer[len + 2]; - + dma_unmap_single(dev->dev.parent, rd->rdma.pbuf, + PKT_BUF_SZ, DMA_FROM_DEVICE); + pkt_status = rd->skb->data[len]; if (pkt_status & SEEQ_RSTAT_FIG) { /* Packet is OK. */ - skb = dev_alloc_skb(len + 2); - - if (skb) { - skb_reserve(skb, 2); - skb_put(skb, len); - - /* Copy out of kseg1 to avoid silly cache flush. */ - skb_copy_to_linear_data(skb, pkt_pointer + 2, len); - skb->protocol = eth_type_trans(skb, dev); - - /* We don't want to receive our own packets */ - if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) { + /* We don't want to receive our own packets */ + if (memcmp(rd->skb->data + 6, dev->dev_addr, ETH_ALEN)) { + if (len > rx_copybreak) { + skb = rd->skb; + newskb = netdev_alloc_skb(dev, PKT_BUF_SZ); + if (!newskb) { + newskb = skb; + skb = NULL; + goto memory_squeeze; + } + skb_reserve(newskb, 2); + } else { + skb = netdev_alloc_skb(dev, len + 2); + if (skb) { + skb_reserve(skb, 2); + skb_copy_to_linear_data(skb, rd->skb->data, len); + } + newskb = rd->skb; + } +memory_squeeze: + if (skb) { + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += len; } else { - /* Silently drop my own packets */ - dev_kfree_skb_irq(skb); + printk(KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", + dev->name); + dev->stats.rx_dropped++; } } else { - printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n", - dev->name); - dev->stats.rx_dropped++; + /* Silently drop my own packets */ + newskb = rd->skb; } } else { record_rx_errors(dev, pkt_status); + newskb = rd->skb; } + rd->skb = newskb; + rd->rdma.pbuf = dma_map_single(dev->dev.parent, + newskb->data - 2, + PKT_BUF_SZ, DMA_FROM_DEVICE); /* Return the entry to the ring pool. */ rd->rdma.cntinfo = RCNTINFO_INIT; sp->rx_new = NEXT_RX(sp->rx_new); + DMA_SYNC_DESC_DEV(dev, rd); + rd = &sp->rx_desc[sp->rx_new]; + DMA_SYNC_DESC_CPU(dev, rd); } + DMA_SYNC_DESC_CPU(dev, &sp->rx_desc[orig_end]); sp->rx_desc[orig_end].rdma.cntinfo &= ~(HPCDMA_EOR); + DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[orig_end]); + DMA_SYNC_DESC_CPU(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]); sp->rx_desc[PREV_RX(sp->rx_new)].rdma.cntinfo |= HPCDMA_EOR; + DMA_SYNC_DESC_DEV(dev, &sp->rx_desc[PREV_RX(sp->rx_new)]); rx_maybe_restart(sp, hregs, sregs); } @@ -358,20 +419,29 @@ static inline void tx_maybe_reset_collisions(struct sgiseeq_private *sp, } } -static inline void kick_tx(struct sgiseeq_tx_desc *td, +static inline void kick_tx(struct net_device *dev, + struct sgiseeq_private *sp, struct hpc3_ethregs *hregs) { + struct sgiseeq_tx_desc *td; + int i = sp->tx_old; + /* If the HPC aint doin nothin, and there are more packets * with ETXD cleared and XIU set we must make very certain * that we restart the HPC else we risk locking up the * adapter. The following code is only safe iff the HPCDMA * is not active! */ + td = &sp->tx_desc[i]; + DMA_SYNC_DESC_CPU(dev, td); while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) == - (HPCDMA_XIU | HPCDMA_ETXD)) - td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext); + (HPCDMA_XIU | HPCDMA_ETXD)) { + i = NEXT_TX(i); + td = &sp->tx_desc[i]; + DMA_SYNC_DESC_CPU(dev, td); + } if (td->tdma.cntinfo & HPCDMA_XIU) { - hregs->tx_ndptr = CPHYSADDR(td); + hregs->tx_ndptr = VIRT_TO_DMA(sp, td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } } @@ -400,11 +470,12 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp for (j = sp->tx_old; j != sp->tx_new; j = NEXT_TX(j)) { td = &sp->tx_desc[j]; + DMA_SYNC_DESC_CPU(dev, td); if (!(td->tdma.cntinfo & (HPCDMA_XIU))) break; if (!(td->tdma.cntinfo & (HPCDMA_ETXD))) { if (!(status & HPC3_ETXCTRL_ACTIVE)) { - hregs->tx_ndptr = CPHYSADDR(td); + hregs->tx_ndptr = VIRT_TO_DMA(sp, td); hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE; } break; @@ -413,6 +484,11 @@ static inline void sgiseeq_tx(struct net_device *dev, struct sgiseeq_private *sp sp->tx_old = NEXT_TX(sp->tx_old); td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE); td->tdma.cntinfo |= HPCDMA_EOX; + if (td->skb) { + dev_kfree_skb_any(td->skb); + td->skb = NULL; + } + DMA_SYNC_DESC_DEV(dev, td); } } @@ -480,6 +556,7 @@ static int sgiseeq_close(struct net_device *dev) /* Shutdown the Seeq. */ reset_hpc3_and_seeq(sp->hregs, sregs); free_irq(irq, dev); + seeq_purge_ring(dev); return 0; } @@ -506,16 +583,22 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) struct hpc3_ethregs *hregs = sp->hregs; unsigned long flags; struct sgiseeq_tx_desc *td; - int skblen, len, entry; + int len, entry; spin_lock_irqsave(&sp->tx_lock, flags); /* Setup... */ - skblen = skb->len; - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; + len = skb->len; + if (len < ETH_ZLEN) { + if (skb_padto(skb, ETH_ZLEN)) + return 0; + len = ETH_ZLEN; + } + dev->stats.tx_bytes += len; entry = sp->tx_new; td = &sp->tx_desc[entry]; + DMA_SYNC_DESC_CPU(dev, td); /* Create entry. There are so many races with adding a new * descriptor to the chain: @@ -530,25 +613,27 @@ static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev) * entry and the HPC got to the end of the chain before we * added this new entry and restarted it. */ - skb_copy_from_linear_data(skb, (char *)(long)td->buf_vaddr, skblen); - if (len != skblen) - memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen); + td->skb = skb; + td->tdma.pbuf = dma_map_single(dev->dev.parent, skb->data, + len, DMA_TO_DEVICE); td->tdma.cntinfo = (len & HPCDMA_BCNT) | HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX; + DMA_SYNC_DESC_DEV(dev, td); if (sp->tx_old != sp->tx_new) { struct sgiseeq_tx_desc *backend; backend = &sp->tx_desc[PREV_TX(sp->tx_new)]; + DMA_SYNC_DESC_CPU(dev, backend); backend->tdma.cntinfo &= ~HPCDMA_EOX; + DMA_SYNC_DESC_DEV(dev, backend); } sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */ /* Maybe kick the HPC back into motion. */ if (!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE)) - kick_tx(&sp->tx_desc[sp->tx_old], hregs); + kick_tx(dev, sp, hregs); dev->trans_start = jiffies; - dev_kfree_skb(skb); if (!TX_BUFFS_AVAIL(sp)) netif_stop_queue(dev); @@ -586,33 +671,41 @@ static void sgiseeq_set_multicast(struct net_device *dev) sgiseeq_reset(dev); } -static inline void setup_tx_ring(struct sgiseeq_tx_desc *buf, int nbufs) +static inline void setup_tx_ring(struct net_device *dev, + struct sgiseeq_tx_desc *buf, + int nbufs) { + struct sgiseeq_private *sp = netdev_priv(dev); int i = 0; while (i < (nbufs - 1)) { - buf[i].tdma.pnext = CPHYSADDR(buf + i + 1); + buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf + i + 1); buf[i].tdma.pbuf = 0; + DMA_SYNC_DESC_DEV(dev, &buf[i]); i++; } - buf[i].tdma.pnext = CPHYSADDR(buf); + buf[i].tdma.pnext = VIRT_TO_DMA(sp, buf); + DMA_SYNC_DESC_DEV(dev, &buf[i]); } -static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) +static inline void setup_rx_ring(struct net_device *dev, + struct sgiseeq_rx_desc *buf, + int nbufs) { + struct sgiseeq_private *sp = netdev_priv(dev); int i = 0; while (i < (nbufs - 1)) { - buf[i].rdma.pnext = CPHYSADDR(buf + i + 1); + buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf + i + 1); buf[i].rdma.pbuf = 0; + DMA_SYNC_DESC_DEV(dev, &buf[i]); i++; } buf[i].rdma.pbuf = 0; - buf[i].rdma.pnext = CPHYSADDR(buf); + buf[i].rdma.pnext = VIRT_TO_DMA(sp, buf); + DMA_SYNC_DESC_DEV(dev, &buf[i]); } -#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) - static int __init sgiseeq_probe(struct platform_device *pdev) { struct sgiseeq_platform_data *pd = pdev->dev.platform_data; @@ -621,7 +714,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev) unsigned int irq = pd->irq; struct sgiseeq_private *sp; struct net_device *dev; - int err, i; + int err; DECLARE_MAC_BUF(mac); dev = alloc_etherdev(sizeof (struct sgiseeq_private)); @@ -635,7 +728,7 @@ static int __init sgiseeq_probe(struct platform_device *pdev) sp = netdev_priv(dev); /* Make private data page aligned */ - sr = dma_alloc_coherent(&pdev->dev, sizeof(*sp->srings), + sr = dma_alloc_noncoherent(&pdev->dev, sizeof(*sp->srings), &sp->srings_dma, GFP_KERNEL); if (!sr) { printk(KERN_ERR "Sgiseeq: Page alloc failed, aborting.\n"); @@ -647,8 +740,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev) sp->tx_desc = sp->srings->txvector; /* A couple calculations now, saves many cycles later. */ - setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS); - setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS); + setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); + setup_tx_ring(dev, sp->tx_desc, SEEQ_TX_BUFFERS); memcpy(dev->dev_addr, pd->mac, ETH_ALEN); @@ -716,8 +809,8 @@ static int __exit sgiseeq_remove(struct platform_device *pdev) struct sgiseeq_private *sp = netdev_priv(dev); unregister_netdev(dev); - dma_free_coherent(&pdev->dev, sizeof(*sp->srings), sp->srings, - sp->srings_dma); + dma_free_noncoherent(&pdev->dev, sizeof(*sp->srings), sp->srings, + sp->srings_dma); free_netdev(dev); platform_set_drvdata(pdev, NULL); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 0857d2c..ec95e49 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -419,7 +419,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, i = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK); if(i){ - printk(KERN_ERR "sis900.c: architecture does not support" + printk(KERN_ERR "sis900.c: architecture does not support " "32bit PCI busmaster DMA\n"); return i; } @@ -1667,7 +1667,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance) /* something strange happened !!! */ if (status & HIBERR) { if(netif_msg_intr(sis_priv)) - printk(KERN_INFO "%s: Abnormal interrupt," + printk(KERN_INFO "%s: Abnormal interrupt, " "status %#8.8x.\n", net_dev->name, status); break; } @@ -1820,7 +1820,7 @@ refill_rx_ring: * how the hardware will react to this kind * of degenerated buffer */ if (netif_msg_rx_err(sis_priv)) - printk(KERN_INFO "%s: Memory squeeze," + printk(KERN_INFO "%s: Memory squeeze, " "deferring packet.\n", net_dev->name); net_dev->stats.rx_dropped++; diff --git a/drivers/net/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c index 0a6f67a..fde4508 100644 --- a/drivers/net/sk98lin/skgemib.c +++ b/drivers/net/sk98lin/skgemib.c @@ -82,7 +82,7 @@ PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, /* defines *******************************************************************/ -#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) +#define ID_TABLE_SIZE ARRAY_SIZE(IdTable) /* global variables **********************************************************/ diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c index b36dd9a..876bb21 100644 --- a/drivers/net/sk98lin/skgepnmi.c +++ b/drivers/net/sk98lin/skgepnmi.c @@ -383,23 +383,11 @@ int Level) /* Initialization level */ SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("CounterOffset struct size (%d) differs from" + ("CounterOffset struct size (%d) differs from " "SK_PNMI_MAX_IDX (%d)\n", SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); } - if (SK_PNMI_MAX_IDX != - (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("StatAddr table size (%d) differs from " - "SK_PNMI_MAX_IDX (%d)\n", - (sizeof(StatAddr) / - (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), - SK_PNMI_MAX_IDX)); - } #endif /* SK_PNMI_CHECK */ break; diff --git a/drivers/net/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c index 3e7aa49..e5ee6d6 100644 --- a/drivers/net/sk98lin/skgesirq.c +++ b/drivers/net/sk98lin/skgesirq.c @@ -892,7 +892,7 @@ int Port) /* Which port should be checked */ */ RxCts = 0; - for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { + for (i = 0; i < ARRAY_SIZE(SkGeRxRegs); i++) { (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 6197afb..de4175c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -64,7 +64,6 @@ #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) #define RX_DEF_PENDING RX_MAX_PENDING -#define RX_SKB_ALIGN 8 #define TX_RING_SIZE 512 #define TX_DEF_PENDING (TX_RING_SIZE - 1) @@ -1171,24 +1170,32 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp /* * Allocate an skb for receiving. If the MTU is large enough * make the skb non-linear with a fragment list of pages. - * - * It appears the hardware has a bug in the FIFO logic that - * cause it to hang if the FIFO gets overrun and the receive buffer - * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is - * aligned except if slab debugging is enabled. */ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) { struct sk_buff *skb; - unsigned long p; int i; - skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN); - if (!skb) - goto nomem; - - p = (unsigned long) skb->data; - skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); + if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) { + unsigned char *start; + /* + * Workaround for a bug in FIFO that cause hang + * if the FIFO if the receive buffer is not 64 byte aligned. + * The buffer returned from netdev_alloc_skb is + * aligned except if slab debugging is enabled. + */ + skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8); + if (!skb) + goto nomem; + start = PTR_ALIGN(skb->data, 8); + skb_reserve(skb, start - skb->data); + } else { + skb = netdev_alloc_skb(sky2->netdev, + sky2->rx_data_size + NET_IP_ALIGN); + if (!skb) + goto nomem; + skb_reserve(skb, NET_IP_ALIGN); + } for (i = 0; i < sky2->rx_nfrags; i++) { struct page *page = alloc_page(GFP_ATOMIC); @@ -1224,7 +1231,7 @@ static int sky2_rx_start(struct sky2_port *sky2) struct sky2_hw *hw = sky2->hw; struct rx_ring_info *re; unsigned rxq = rxqaddr[sky2->port]; - unsigned i, size, space, thresh; + unsigned i, size, thresh; sky2->rx_put = sky2->rx_next = 0; sky2_qset(hw, rxq); @@ -1251,28 +1258,18 @@ static int sky2_rx_start(struct sky2_port *sky2) /* Stopping point for hardware truncation */ thresh = (size - 8) / sizeof(u32); - /* Account for overhead of skb - to avoid order > 0 allocation */ - space = SKB_DATA_ALIGN(size) + NET_SKB_PAD - + sizeof(struct skb_shared_info); - - sky2->rx_nfrags = space >> PAGE_SHIFT; + sky2->rx_nfrags = size >> PAGE_SHIFT; BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr)); - if (sky2->rx_nfrags != 0) { - /* Compute residue after pages */ - space = sky2->rx_nfrags << PAGE_SHIFT; + /* Compute residue after pages */ + size -= sky2->rx_nfrags << PAGE_SHIFT; - if (space < size) - size -= space; - else - size = 0; + /* Optimize to handle small packets and headers */ + if (size < copybreak) + size = copybreak; + if (size < ETH_HLEN) + size = ETH_HLEN; - /* Optimize to handle small packets and headers */ - if (size < copybreak) - size = copybreak; - if (size < ETH_HLEN) - size = ETH_HLEN; - } sky2->rx_data_size = size; /* Fill Rx ring */ diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 251a3ce..5a55ede 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -11,9 +11,11 @@ * Fixes: * Alan Cox : Sanity checks and avoid tx overruns. * Has a new sl->mtu field. - * Alan Cox : Found cause of overrun. ifconfig sl0 mtu upwards. - * Driver now spots this and grows/shrinks its buffers(hack!). - * Memory leak if you run out of memory setting up a slip driver fixed. + * Alan Cox : Found cause of overrun. ifconfig sl0 + * mtu upwards. Driver now spots this + * and grows/shrinks its buffers(hack!). + * Memory leak if you run out of memory + * setting up a slip driver fixed. * Matt Dillon : Printable slip (borrowed from NET2E) * Pauline Middelink : Slip driver fixes. * Alan Cox : Honours the old SL_COMPRESSED flag @@ -29,7 +31,8 @@ * buffering from 4096 to 256 bytes. * Improving SLIP response time. * CONFIG_SLIP_MODE_SLIP6. - * ifconfig sl? up & down now works correctly. + * ifconfig sl? up & down now works + * correctly. * Modularization. * Alan Cox : Oops - fix AX.25 buffer lengths * Dmitry Gorodchanin : Even more cleanups. Preserve CSLIP @@ -43,15 +46,18 @@ * device entries, just reg./unreg. them * as they are needed. We kfree() them * at module cleanup. - * With MODULE-loading ``insmod'', user can - * issue parameter: slip_maxdev=1024 - * (Or how much he/she wants.. Default is 256) - * * Stanislav Voronyi : Slip line checking, with ideas taken - * from multislip BSDI driver which was written - * by Igor Chechik, RELCOM Corp. Only algorithms - * have been ported to Linux SLIP driver. + * With MODULE-loading ``insmod'', user + * can issue parameter: slip_maxdev=1024 + * (Or how much he/she wants.. Default + * is 256) + * Stanislav Voronyi : Slip line checking, with ideas taken + * from multislip BSDI driver which was + * written by Igor Chechik, RELCOM Corp. + * Only algorithms have been ported to + * Linux SLIP driver. * Vitaly E. Lavrov : Sane behaviour on tty hangup. - * Alexey Kuznetsov : Cleanup interfaces to tty&netdevice modules. + * Alexey Kuznetsov : Cleanup interfaces to tty & netdevice + * modules. */ #define SL_CHECK_TRANSMIT @@ -99,7 +105,7 @@ static void slip_unesc6(struct slip *sl, unsigned char c); #ifdef CONFIG_SLIP_SMART static void sl_keepalive(unsigned long sls); static void sl_outfill(unsigned long sls); -static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); +static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #endif /******************************** @@ -117,15 +123,14 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd); Allocate channel buffers. */ -static int -sl_alloc_bufs(struct slip *sl, int mtu) +static int sl_alloc_bufs(struct slip *sl, int mtu) { int err = -ENOBUFS; unsigned long len; - char * rbuff = NULL; - char * xbuff = NULL; + char *rbuff = NULL; + char *xbuff = NULL; #ifdef SL_INCLUDE_CSLIP - char * cbuff = NULL; + char *cbuff = NULL; struct slcompress *slcomp = NULL; #endif @@ -195,8 +200,7 @@ err_exit: } /* Free a SLIP channel buffers. */ -static void -sl_free_bufs(struct slip *sl) +static void sl_free_bufs(struct slip *sl) { /* Free all SLIP frame buffers. */ kfree(xchg(&sl->rbuff, NULL)); @@ -248,7 +252,6 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) } goto done; } - spin_lock_bh(&sl->lock); err = -ENODEV; @@ -298,23 +301,20 @@ done: /* Set the "sending" flag. This must be atomic hence the set_bit. */ -static inline void -sl_lock(struct slip *sl) +static inline void sl_lock(struct slip *sl) { netif_stop_queue(sl->dev); } /* Clear the "sending" flag. This must be atomic, hence the ASM. */ -static inline void -sl_unlock(struct slip *sl) +static inline void sl_unlock(struct slip *sl) { netif_wake_queue(sl->dev); } /* Send one completely decapsulated IP datagram to the IP layer. */ -static void -sl_bump(struct slip *sl) +static void sl_bump(struct slip *sl) { struct sk_buff *skb; int count; @@ -322,22 +322,22 @@ sl_bump(struct slip *sl) count = sl->rcount; #ifdef SL_INCLUDE_CSLIP if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { - unsigned char c; - if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) { + unsigned char c = sl->rbuff[0]; + 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); return; } - /* make sure we've reserved enough space for uncompress to use */ + /* make sure we've reserved enough space for uncompress + to use */ if (count + 80 > sl->buffsize) { sl->rx_over_errors++; return; } count = slhc_uncompress(sl->slcomp, sl->rbuff, count); - if (count <= 0) { + if (count <= 0) return; - } } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) { if (!(sl->mode & SL_MODE_CSLIP)) { /* turn on header compression */ @@ -346,33 +346,31 @@ sl_bump(struct slip *sl) printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name); } sl->rbuff[0] &= 0x4f; - if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) { + if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) return; - } } } #endif /* SL_INCLUDE_CSLIP */ - sl->rx_bytes+=count; + sl->rx_bytes += count; skb = dev_alloc_skb(count); - if (skb == NULL) { + if (skb == NULL) { printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name); sl->rx_dropped++; return; } skb->dev = sl->dev; - memcpy(skb_put(skb,count), sl->rbuff, count); + memcpy(skb_put(skb, count), sl->rbuff, count); skb_reset_mac_header(skb); - skb->protocol=htons(ETH_P_IP); + skb->protocol = htons(ETH_P_IP); netif_rx(skb); sl->dev->last_rx = jiffies; sl->rx_packets++; } /* Encapsulate one IP datagram and stuff into a TTY queue. */ -static void -sl_encaps(struct slip *sl, unsigned char *icp, int len) +static void sl_encaps(struct slip *sl, unsigned char *icp, int len) { unsigned char *p; int actual, count; @@ -386,12 +384,11 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) p = icp; #ifdef SL_INCLUDE_CSLIP - if (sl->mode & SL_MODE_CSLIP) { + if (sl->mode & SL_MODE_CSLIP) len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1); - } #endif #ifdef CONFIG_SLIP_MODE_SLIP6 - if(sl->mode & SL_MODE_SLIP6) + if (sl->mode & SL_MODE_SLIP6) count = slip_esc6(p, (unsigned char *) sl->xbuff, len); else #endif @@ -425,12 +422,12 @@ sl_encaps(struct slip *sl, unsigned char *icp, int len) static void slip_write_wakeup(struct tty_struct *tty) { int actual; - struct slip *sl = (struct slip *) tty->disc_data; + struct slip *sl = tty->disc_data; /* First make sure we're connected. */ - if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) { + if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; - } + if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ @@ -463,15 +460,15 @@ static void sl_tx_timeout(struct net_device *dev) /* 20 sec timeout not reached */ goto out; } - printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? - "bad line quality" : "driver error"); + printk(KERN_WARNING "%s: transmit timed out, %s?\n", + dev->name, + (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ? + "bad line quality" : "driver error"); sl->xleft = 0; sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); sl_unlock(sl); #endif } - out: spin_unlock(&sl->lock); } @@ -484,7 +481,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev) struct slip *sl = netdev_priv(dev); spin_lock(&sl->lock); - if (!netif_running(dev)) { + if (!netif_running(dev)) { spin_unlock(&sl->lock); printk(KERN_WARNING "%s: xmit call when iface is down\n", dev->name); dev_kfree_skb(skb); @@ -497,7 +494,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev) } sl_lock(sl); - sl->tx_bytes+=skb->len; + sl->tx_bytes += skb->len; sl_encaps(sl, skb->data, skb->len); spin_unlock(&sl->lock); @@ -536,7 +533,7 @@ static int sl_open(struct net_device *dev) { struct slip *sl = netdev_priv(dev); - if (sl->tty==NULL) + if (sl->tty == NULL) return -ENODEV; sl->flags &= (1 << SLF_INUSE); @@ -657,20 +654,19 @@ static void sl_setup(struct net_device *dev) * in parallel */ -static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) +static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, + char *fp, int count) { - struct slip *sl = (struct slip *) tty->disc_data; + struct slip *sl = tty->disc_data; - if (!sl || sl->magic != SLIP_MAGIC || - !netif_running(sl->dev)) + if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) return; /* Read the characters out of the buffer */ while (count--) { if (fp && *fp++) { - if (!test_and_set_bit(SLF_ERROR, &sl->flags)) { + if (!test_and_set_bit(SLF_ERROR, &sl->flags)) sl->rx_errors++; - } cp++; continue; } @@ -688,7 +684,6 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, ch ************************************/ /* Collect hanged up channels */ - static void sl_sync(void) { int i; @@ -696,21 +691,21 @@ static void sl_sync(void) struct slip *sl; for (i = 0; i < slip_maxdev; i++) { - if ((dev = slip_devs[i]) == NULL) + dev = slip_devs[i]; + if (dev == NULL) break; sl = netdev_priv(dev); if (sl->tty || sl->leased) continue; - if (dev->flags&IFF_UP) + if (dev->flags & IFF_UP) dev_close(dev); } } /* Find a free SLIP channel, and link in this `tty' line. */ -static struct slip * -sl_alloc(dev_t line) +static struct slip *sl_alloc(dev_t line) { int i; int sel = -1; @@ -805,15 +800,15 @@ sl_alloc(dev_t line) spin_lock_init(&sl->lock); sl->mode = SL_MODE_DEFAULT; #ifdef CONFIG_SLIP_SMART - init_timer(&sl->keepalive_timer); /* initialize timer_list struct */ - sl->keepalive_timer.data=(unsigned long)sl; - sl->keepalive_timer.function=sl_keepalive; + /* initialize timer_list struct */ + init_timer(&sl->keepalive_timer); + sl->keepalive_timer.data = (unsigned long)sl; + sl->keepalive_timer.function = sl_keepalive; init_timer(&sl->outfill_timer); - sl->outfill_timer.data=(unsigned long)sl; - sl->outfill_timer.function=sl_outfill; + sl->outfill_timer.data = (unsigned long)sl; + sl->outfill_timer.function = sl_outfill; #endif slip_devs[i] = dev; - return sl; } @@ -832,7 +827,7 @@ static int slip_open(struct tty_struct *tty) struct slip *sl; int err; - if(!capable(CAP_NET_ADMIN)) + if (!capable(CAP_NET_ADMIN)) return -EPERM; /* RTnetlink lock is misused here to serialize concurrent @@ -844,7 +839,7 @@ static int slip_open(struct tty_struct *tty) /* Collect hanged up channels. */ sl_sync(); - sl = (struct slip *) tty->disc_data; + sl = tty->disc_data; err = -EEXIST; /* First make sure we're not already connected. */ @@ -853,7 +848,8 @@ static int slip_open(struct tty_struct *tty) /* OK. Find a free SLIP channel to use. */ err = -ENFILE; - if ((sl = sl_alloc(tty_devnum(tty))) == NULL) + sl = sl_alloc(tty_devnum(tty)); + if (sl == NULL) goto err_exit; sl->tty = tty; @@ -863,23 +859,25 @@ static int slip_open(struct tty_struct *tty) if (!test_bit(SLF_INUSE, &sl->flags)) { /* Perform the low-level SLIP initialization. */ - if ((err = sl_alloc_bufs(sl, SL_MTU)) != 0) + err = sl_alloc_bufs(sl, SL_MTU); + if (err) goto err_free_chan; set_bit(SLF_INUSE, &sl->flags); - if ((err = register_netdevice(sl->dev))) + err = register_netdevice(sl->dev); + if (err) goto err_free_bufs; } #ifdef CONFIG_SLIP_SMART if (sl->keepalive) { - sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ; - add_timer (&sl->keepalive_timer); + sl->keepalive_timer.expires = jiffies + sl->keepalive * HZ; + add_timer(&sl->keepalive_timer); } if (sl->outfill) { - sl->outfill_timer.expires=jiffies+sl->outfill*HZ; - add_timer (&sl->outfill_timer); + sl->outfill_timer.expires = jiffies + sl->outfill * HZ; + add_timer(&sl->outfill_timer); } #endif @@ -928,10 +926,9 @@ err_exit: * This means flushing out any pending queues, and then returning. This * call is serialized against other ldisc functions. */ -static void -slip_close(struct tty_struct *tty) +static void slip_close(struct tty_struct *tty) { - struct slip *sl = (struct slip *) tty->disc_data; + struct slip *sl = tty->disc_data; /* First make sure we're connected. */ if (!sl || sl->magic != SLIP_MAGIC || sl->tty != tty) @@ -955,8 +952,7 @@ slip_close(struct tty_struct *tty) * STANDARD SLIP ENCAPSULATION * ************************************************************************/ -static int -slip_esc(unsigned char *s, unsigned char *d, int len) +static int slip_esc(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; @@ -975,16 +971,16 @@ slip_esc(unsigned char *s, unsigned char *d, int len) */ while (len-- > 0) { - switch(c = *s++) { - case END: + switch (c = *s++) { + case END: *ptr++ = ESC; *ptr++ = ESC_END; break; - case ESC: + case ESC: *ptr++ = ESC; *ptr++ = ESC_ESC; break; - default: + default: *ptr++ = c; break; } @@ -996,33 +992,31 @@ slip_esc(unsigned char *s, unsigned char *d, int len) static void slip_unesc(struct slip *sl, unsigned char s) { - switch(s) { - case END: + switch (s) { + case END: #ifdef CONFIG_SLIP_SMART /* drop keeptest bit = VSV */ if (test_bit(SLF_KEEPTEST, &sl->flags)) clear_bit(SLF_KEEPTEST, &sl->flags); #endif - if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { + if (!test_and_clear_bit(SLF_ERROR, &sl->flags) + && (sl->rcount > 2)) sl_bump(sl); - } clear_bit(SLF_ESCAPE, &sl->flags); sl->rcount = 0; return; - case ESC: + case ESC: set_bit(SLF_ESCAPE, &sl->flags); return; - case ESC_ESC: - if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { + case ESC_ESC: + if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = ESC; - } break; - case ESC_END: - if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) { + case ESC_END: + if (test_and_clear_bit(SLF_ESCAPE, &sl->flags)) s = END; - } break; } if (!test_bit(SLF_ERROR, &sl->flags)) { @@ -1041,8 +1035,7 @@ static void slip_unesc(struct slip *sl, unsigned char s) * 6 BIT SLIP ENCAPSULATION * ************************************************************************/ -int -slip_esc6(unsigned char *s, unsigned char *d, int len) +static int slip_esc6(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; unsigned char c; @@ -1079,8 +1072,7 @@ slip_esc6(unsigned char *s, unsigned char *d, int len) return ptr - d; } -void -slip_unesc6(struct slip *sl, unsigned char s) +static void slip_unesc6(struct slip *sl, unsigned char s) { unsigned char c; @@ -1091,13 +1083,13 @@ slip_unesc6(struct slip *sl, unsigned char s) clear_bit(SLF_KEEPTEST, &sl->flags); #endif - if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2)) { + if (!test_and_clear_bit(SLF_ERROR, &sl->flags) + && (sl->rcount > 2)) sl_bump(sl); - } sl->rcount = 0; sl->xbits = 0; sl->xdata = 0; - } else if (s >= 0x30 && s < 0x70) { + } else if (s >= 0x30 && s < 0x70) { sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F); sl->xbits += 6; if (sl->xbits >= 8) { @@ -1112,24 +1104,24 @@ slip_unesc6(struct slip *sl, unsigned char s) set_bit(SLF_ERROR, &sl->flags); } } - } + } } #endif /* CONFIG_SLIP_MODE_SLIP6 */ /* Perform I/O control on an active SLIP channel. */ -static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) +static int slip_ioctl(struct tty_struct *tty, struct file *file, + unsigned int cmd, unsigned long arg) { - struct slip *sl = (struct slip *) tty->disc_data; + struct slip *sl = tty->disc_data; unsigned int tmp; int __user *p = (int __user *)arg; /* First make sure we're connected. */ - if (!sl || sl->magic != SLIP_MAGIC) { + if (!sl || sl->magic != SLIP_MAGIC) return -EINVAL; - } - switch(cmd) { - case SIOCGIFNAME: + switch (cmd) { + case SIOCGIFNAME: tmp = strlen(sl->dev->name) + 1; if (copy_to_user((void __user *)arg, sl->dev->name, tmp)) return -EFAULT; @@ -1144,34 +1136,31 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm if (get_user(tmp, p)) return -EFAULT; #ifndef SL_INCLUDE_CSLIP - if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) { + if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE)) return -EINVAL; - } #else if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) == - (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) { + (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) /* return -EINVAL; */ tmp &= ~SL_MODE_ADAPTIVE; - } #endif #ifndef CONFIG_SLIP_MODE_SLIP6 - if (tmp & SL_MODE_SLIP6) { + if (tmp & SL_MODE_SLIP6) return -EINVAL; - } #endif sl->mode = tmp; - sl->dev->type = ARPHRD_SLIP+sl->mode; + sl->dev->type = ARPHRD_SLIP + sl->mode; return 0; - case SIOCSIFHWADDR: + case SIOCSIFHWADDR: return -EINVAL; #ifdef CONFIG_SLIP_SMART /* VSV changes start here */ - case SIOCSKEEPALIVE: + case SIOCSKEEPALIVE: if (get_user(tmp, p)) return -EFAULT; - if (tmp > 255) /* max for unchar */ + if (tmp > 255) /* max for unchar */ return -EINVAL; spin_lock_bh(&sl->lock); @@ -1179,40 +1168,42 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm spin_unlock_bh(&sl->lock); return -ENODEV; } - if ((sl->keepalive = (unchar) tmp) != 0) { - mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); + sl->keepalive = (u8)tmp; + if (sl->keepalive != 0) { + mod_timer(&sl->keepalive_timer, + jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); - } else { - del_timer (&sl->keepalive_timer); - } + } else + del_timer(&sl->keepalive_timer); spin_unlock_bh(&sl->lock); return 0; - case SIOCGKEEPALIVE: + case SIOCGKEEPALIVE: if (put_user(sl->keepalive, p)) return -EFAULT; return 0; - case SIOCSOUTFILL: + case SIOCSOUTFILL: if (get_user(tmp, p)) return -EFAULT; - if (tmp > 255) /* max for unchar */ + if (tmp > 255) /* max for unchar */ return -EINVAL; spin_lock_bh(&sl->lock); if (!sl->tty) { spin_unlock_bh(&sl->lock); return -ENODEV; } - if ((sl->outfill = (unchar) tmp) != 0){ - mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); + sl->outfill = (u8)tmp; + if (sl->outfill != 0) { + mod_timer(&sl->outfill_timer, + jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); - } else { - del_timer (&sl->outfill_timer); - } + } else + del_timer(&sl->outfill_timer); spin_unlock_bh(&sl->lock); - return 0; + return 0; - case SIOCGOUTFILL: + case SIOCGOUTFILL: if (put_user(sl->outfill, p)) return -EFAULT; return 0; @@ -1229,7 +1220,7 @@ static int slip_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm to allow get/set outfill/keepalive parameter by ifconfig */ -static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) +static int sl_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct slip *sl = netdev_priv(dev); unsigned long *p = (unsigned long *)&rq->ifr_ifru; @@ -1244,58 +1235,61 @@ static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd) return -ENODEV; } - switch(cmd){ - case SIOCSKEEPALIVE: + switch (cmd) { + case SIOCSKEEPALIVE: /* max for unchar */ - if ((unsigned)*p > 255) { + if ((unsigned)*p > 255) { spin_unlock_bh(&sl->lock); return -EINVAL; } - sl->keepalive = (unchar) *p; + sl->keepalive = (u8)*p; if (sl->keepalive != 0) { - sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ; - mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); + sl->keepalive_timer.expires = + jiffies + sl->keepalive * HZ; + mod_timer(&sl->keepalive_timer, + jiffies + sl->keepalive * HZ); set_bit(SLF_KEEPTEST, &sl->flags); - } else { - del_timer(&sl->keepalive_timer); - } + } else + del_timer(&sl->keepalive_timer); break; - case SIOCGKEEPALIVE: + case SIOCGKEEPALIVE: *p = sl->keepalive; break; - case SIOCSOUTFILL: - if ((unsigned)*p > 255) { /* max for unchar */ + case SIOCSOUTFILL: + if ((unsigned)*p > 255) { /* max for unchar */ spin_unlock_bh(&sl->lock); return -EINVAL; } - if ((sl->outfill = (unchar)*p) != 0){ - mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); + sl->outfill = (u8)*p; + if (sl->outfill != 0) { + mod_timer(&sl->outfill_timer, + jiffies + sl->outfill * HZ); set_bit(SLF_OUTWAIT, &sl->flags); - } else { - del_timer (&sl->outfill_timer); - } - break; + } else + del_timer(&sl->outfill_timer); + break; - case SIOCGOUTFILL: + case SIOCGOUTFILL: *p = sl->outfill; break; - case SIOCSLEASE: + case SIOCSLEASE: /* Resolve race condition, when ioctl'ing hanged up and opened by another process device. */ - if (sl->tty != current->signal->tty && sl->pid != current->pid) { + if (sl->tty != current->signal->tty && + sl->pid != current->pid) { spin_unlock_bh(&sl->lock); return -EPERM; } sl->leased = 0; - if (*p) + if (*p) sl->leased = 1; - break; + break; - case SIOCGLEASE: + case SIOCGLEASE: *p = sl->leased; }; spin_unlock_bh(&sl->lock); @@ -1327,7 +1321,7 @@ static int __init slip_init(void) " (6 bit encapsulation enabled)" #endif ".\n", - SLIP_VERSION, slip_maxdev ); + SLIP_VERSION, slip_maxdev); #if defined(SL_INCLUDE_CSLIP) printk(KERN_INFO "CSLIP: code copyright 1989 Regents of the University of California.\n"); #endif @@ -1335,14 +1329,16 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif - slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); + slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, + GFP_KERNEL); if (!slip_devs) { - printk(KERN_ERR "SLIP: Can't allocate slip devices array! Uaargh! (-> No SLIP available)\n"); + printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n"); return -ENOMEM; } /* Fill in our line protocol discipline, and register it */ - if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0) { + status = tty_register_ldisc(N_SLIP, &sl_ldisc); + if (status != 0) { printk(KERN_ERR "SLIP: can't register line discipline (err = %d)\n", status); kfree(slip_devs); } @@ -1402,10 +1398,9 @@ static void __exit slip_exit(void) kfree(slip_devs); slip_devs = NULL; - if ((i = tty_unregister_ldisc(N_SLIP))) - { + i = tty_unregister_ldisc(N_SLIP); + if (i != 0) printk(KERN_ERR "SLIP: can't unregister line discipline (err = %d)\n", i); - } } module_init(slip_init); @@ -1419,17 +1414,15 @@ module_exit(slip_exit); static void sl_outfill(unsigned long sls) { - struct slip *sl=(struct slip *)sls; + struct slip *sl = (struct slip *)sls; spin_lock(&sl->lock); if (sl->tty == NULL) goto out; - if(sl->outfill) - { - if( test_bit(SLF_OUTWAIT, &sl->flags) ) - { + if (sl->outfill) { + if (test_bit(SLF_OUTWAIT, &sl->flags)) { /* no packets were transmitted, do outfill */ #ifdef CONFIG_SLIP_MODE_SLIP6 unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END; @@ -1437,13 +1430,11 @@ static void sl_outfill(unsigned long sls) unsigned char s = END; #endif /* put END into tty queue. Is it right ??? */ - if (!netif_queue_stopped(sl->dev)) - { + if (!netif_queue_stopped(sl->dev)) { /* if device busy no outfill */ sl->tty->driver->write(sl->tty, &s, 1); } - } - else + } else set_bit(SLF_OUTWAIT, &sl->flags); mod_timer(&sl->outfill_timer, jiffies+sl->outfill*HZ); @@ -1454,31 +1445,29 @@ out: static void sl_keepalive(unsigned long sls) { - struct slip *sl=(struct slip *)sls; + struct slip *sl = (struct slip *)sls; spin_lock(&sl->lock); if (sl->tty == NULL) goto out; - if( sl->keepalive) - { - if(test_bit(SLF_KEEPTEST, &sl->flags)) - { + if (sl->keepalive) { + if (test_bit(SLF_KEEPTEST, &sl->flags)) { /* keepalive still high :(, we must hangup */ - if( sl->outfill ) /* outfill timer must be deleted too */ + if (sl->outfill) + /* outfill timer must be deleted too */ (void)del_timer(&sl->outfill_timer); printk(KERN_DEBUG "%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name); - tty_hangup(sl->tty); /* this must hangup tty & close slip */ + /* this must hangup tty & close slip */ + tty_hangup(sl->tty); /* I think we need not something else */ goto out; - } - else + } else set_bit(SLF_KEEPTEST, &sl->flags); mod_timer(&sl->keepalive_timer, jiffies+sl->keepalive*HZ); } - out: spin_unlock(&sl->lock); } diff --git a/drivers/net/smc9194.c b/drivers/net/smc9194.c index cb2698d..de67744 100644 --- a/drivers/net/smc9194.c +++ b/drivers/net/smc9194.c @@ -906,7 +906,7 @@ static int __init smc_probe(struct net_device *dev, int ioaddr) SMC_SELECT_BANK(1); base_address_register = inw( ioaddr + BASE ); if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) ) { - printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)." + printk(CARDNAME ": IOADDR %x doesn't match configuration (%x). " "Probably not a SMC chip\n", ioaddr, base_address_register >> 3 & 0x3E0 ); /* well, the base address register didn't match. Must not have diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index ff98f5d..f12e727 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1596,9 +1596,7 @@ static const struct ethtool_ops ethtool_ops = { static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct netdev_private *np = netdev_priv(dev); - void __iomem *ioaddr = np->base; int rc; - int i; if (!netif_running(dev)) return -EINVAL; @@ -1606,30 +1604,6 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) spin_lock_irq(&np->lock); rc = generic_mii_ioctl(&np->mii_if, if_mii(rq), cmd, NULL); spin_unlock_irq(&np->lock); - switch (cmd) { - case SIOCDEVPRIVATE: - for (i=0; itx_ring_dma + i*sizeof(*np->tx_ring)), - le32_to_cpu(np->tx_ring[i].next_desc), - le32_to_cpu(np->tx_ring[i].status), - (le32_to_cpu(np->tx_ring[i].status) >> 2) - & 0xff, - le32_to_cpu(np->tx_ring[i].frag[0].addr), - le32_to_cpu(np->tx_ring[i].frag[0].length)); - } - printk(KERN_DEBUG "TxListPtr=%08x netif_queue_stopped=%d\n", - ioread32(np->base + TxListPtr), - netif_queue_stopped(dev)); - printk(KERN_DEBUG "cur_tx=%d(%02x) dirty_tx=%d(%02x)\n", - np->cur_tx, np->cur_tx % TX_RING_SIZE, - np->dirty_tx, np->dirty_tx % TX_RING_SIZE); - printk(KERN_DEBUG "cur_rx=%d dirty_rx=%d\n", np->cur_rx, np->dirty_rx); - printk(KERN_DEBUG "cur_task=%d\n", np->cur_task); - printk(KERN_DEBUG "TxStatus=%04x\n", ioread16(ioaddr + TxStatus)); - return 0; - } - return rc; } diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 21230c9..17585e5 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -621,7 +621,7 @@ err: static void __init bdx_firmware_endianess(void) { int i; - for (i = 0; i < sizeof(s_firmLoad) / sizeof(u32); i++) + for (i = 0; i < ARRAY_SIZE(s_firmLoad); i++) s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]); } @@ -2174,8 +2174,7 @@ bdx_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) strlcat(drvinfo->bus_info, pci_name(priv->pdev), sizeof(drvinfo->bus_info)); - drvinfo->n_stats = ((priv->stats_flag) ? - (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) : 0); + drvinfo->n_stats = ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0); drvinfo->testinfo_len = 0; drvinfo->regdump_len = 0; drvinfo->eedump_len = 0; @@ -2375,10 +2374,9 @@ static void bdx_get_strings(struct net_device *netdev, u32 stringset, u8 *data) static int bdx_get_stats_count(struct net_device *netdev) { struct bdx_priv *priv = netdev->priv; - BDX_ASSERT(sizeof(bdx_stat_names) / ETH_GSTRING_LEN + BDX_ASSERT(ARRAY_SIZE(bdx_stat_names) != sizeof(struct bdx_stats) / sizeof(u64)); - return ((priv->stats_flag) ? (sizeof(bdx_stat_names) / ETH_GSTRING_LEN) - : 0); + return ((priv->stats_flag) ? ARRAY_SIZE(bdx_stat_names) : 0); } /* diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 41f34bb..9583682 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -4175,7 +4175,7 @@ de4x5_bad_srom(struct de4x5_private *lp) { int i, status = 0; - for (i=0; isrom, (char *)&enet_det[i], 3) && !de4x5_strncmp((char *)&lp->srom+0x10, (char *)&enet_det[i], 3)) { if (i == 0) { @@ -4195,7 +4195,7 @@ de4x5_strncmp(char *a, char *b, int n) { int ret=0; - for (;n && !ret;n--) { + for (;n && !ret; n--) { ret = *a++ - *b++; } diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 7f68990..329c938 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3614,9 +3614,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) ugeth_vdbg("%s: IN", __FUNCTION__); - if (!ugeth) - return IRQ_NONE; - uccf = ugeth->uccf; ug_info = ugeth->ug_info; diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 1ffdd10..633a511 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -101,17 +101,16 @@ static void dm_write_async_callback(struct urb *urb) usb_free_urb(urb); } -static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) +static void dm_write_async_helper(struct usbnet *dev, u8 reg, u8 value, + u16 length, void *data) { struct usb_ctrlrequest *req; struct urb *urb; int status; - devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length); - urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - deverr(dev, "Error allocating URB in dm_write_async!"); + deverr(dev, "Error allocating URB in dm_write_async_helper!"); return; } @@ -123,8 +122,8 @@ static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) } req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - req->bRequest = DM_WRITE_REGS; - req->wValue = 0; + req->bRequest = length ? DM_WRITE_REGS : DM_WRITE_REG; + req->wValue = cpu_to_le16(value); req->wIndex = cpu_to_le16(reg); req->wLength = cpu_to_le16(length); @@ -142,45 +141,19 @@ static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) } } -static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) +static void dm_write_async(struct usbnet *dev, u8 reg, u16 length, void *data) { - struct usb_ctrlrequest *req; - struct urb *urb; - int status; + devdbg(dev, "dm_write_async() reg=0x%02x length=%d", reg, length); + dm_write_async_helper(dev, reg, 0, length, data); +} + +static void dm_write_reg_async(struct usbnet *dev, u8 reg, u8 value) +{ devdbg(dev, "dm_write_reg_async() reg=0x%02x value=0x%02x", reg, value); - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) { - deverr(dev, "Error allocating URB in dm_write_async!"); - return; - } - - req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); - if (!req) { - deverr(dev, "Failed to allocate memory for control request"); - usb_free_urb(urb); - return; - } - - req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - req->bRequest = DM_WRITE_REG; - req->wValue = cpu_to_le16(value); - req->wIndex = cpu_to_le16(reg); - req->wLength = 0; - - usb_fill_control_urb(urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), - (void *)req, NULL, 0, dm_write_async_callback, req); - - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status < 0) { - deverr(dev, "Error submitting the control message: status=%d", - status); - kfree(req); - usb_free_urb(urb); - } + dm_write_async_helper(dev, reg, value, 0, NULL); } static int dm_read_shared_word(struct usbnet *dev, int phy, u8 reg, u16 *value) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 07263cd..87c180b 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -1338,7 +1338,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance) if (debug > 2 && ioread8(ioaddr+ChipCmd) & CmdTxOn) printk(KERN_WARNING "%s: " - "rhine_interrupt() Tx engine" + "rhine_interrupt() Tx engine " "still on.\n", dev->name); } rhine_tx(dev); diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 12dae8e..cf27bf4 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -1498,9 +1498,9 @@ do_bottom_half_rx(struct fst_card_info *card) * Dev_id is our fst_card_info pointer */ static irqreturn_t -fst_intr(int irq, void *dev_id) +fst_intr(int dummy, void *dev_id) { - struct fst_card_info *card; + struct fst_card_info *card = dev_id; struct fst_port_info *port; int rdidx; /* Event buffer indices */ int wridx; @@ -1509,17 +1509,12 @@ fst_intr(int irq, void *dev_id) unsigned int do_card_interrupt; unsigned int int_retry_count; - if ((card = dev_id) == NULL) { - dbg(DBG_INTR, "intr: spurious %d\n", irq); - return IRQ_NONE; - } - /* * Check to see if the interrupt was for this card * return if not * Note that the call to clear the interrupt is important */ - dbg(DBG_INTR, "intr: %d %p\n", irq, card); + dbg(DBG_INTR, "intr: %d %p\n", card->irq, card); if (card->state != FST_RUNNING) { printk_err ("Interrupt received for card %d in a non running state (%d)\n", diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index 05df0a3..73e2f27 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -867,7 +867,7 @@ static void sdla_receive(struct net_device *dev) spin_unlock_irqrestore(&sdla_lock, flags); } -static irqreturn_t sdla_isr(int irq, void *dev_id) +static irqreturn_t sdla_isr(int dummy, void *dev_id) { struct net_device *dev; struct frad_local *flp; @@ -879,7 +879,8 @@ static irqreturn_t sdla_isr(int irq, void *dev_id) if (!flp->initialized) { - printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", dev->name, irq); + printk(KERN_WARNING "%s: irq %d for uninitialized device.\n", + dev->name, dev->irq); return IRQ_NONE; } diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 8e320b7..ad8c865 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -743,7 +743,7 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, }while (time_after(timeout, jiffies)); if (!stat) { - printk(KERN_WARNING "wanXL %s: timeout while initializing card" + printk(KERN_WARNING "wanXL %s: timeout while initializing card " "firmware\n", pci_name(pdev)); wanxl_pci_remove_one(pdev); return -ENODEV; diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 6f32b53..d48f7d1 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -52,7 +52,8 @@ obj-$(CONFIG_RTL8187) += rtl8187.o obj-$(CONFIG_ADM8211) += adm8211.o -obj-$(CONFIG_IWLWIFI) += iwlwifi/ +obj-$(CONFIG_IWL3945) += iwlwifi/ +obj-$(CONFIG_IWL4965) += iwlwifi/ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54common.o diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 074055e..42670ac 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -3177,8 +3177,9 @@ static int airo_thread(void *data) { return 0; } -static irqreturn_t airo_interrupt ( int irq, void* dev_id) { - struct net_device *dev = (struct net_device *)dev_id; +static irqreturn_t airo_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; u16 status; u16 fid; struct airo_info *apriv = dev->priv; @@ -6407,9 +6408,8 @@ static int airo_set_encode(struct net_device *dev, set_wep_key(local, index, NULL, 0, perm, 1); } else /* Don't complain if only change the mode */ - if(!dwrq->flags & IW_ENCODE_MODE) { + if (!(dwrq->flags & IW_ENCODE_MODE)) return -EINVAL; - } } /* Read the flags */ if(dwrq->flags & IW_ENCODE_DISABLED) diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 059ce3f..32fbaf2 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1759,9 +1759,8 @@ static int atmel_set_encode(struct net_device *dev, priv->default_key = index; } else /* Don't complain if only change the mode */ - if (!dwrq->flags & IW_ENCODE_MODE) { + if (!(dwrq->flags & IW_ENCODE_MODE)) return -EINVAL; - } } /* Read the flags */ if (dwrq->flags & IW_ENCODE_DISABLED) { diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 485e59e..dc27047 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -5,6 +5,7 @@ b43-y += phy.o b43-y += sysfs.o b43-y += xmit.o b43-y += lo.o +b43-y += wa.o # b43 RFKILL button support b43-$(CONFIG_B43_RFKILL) += rfkill.o # b43 LED support diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index a28ad23..6acaa3d 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -391,6 +391,8 @@ enum { #define B43_DEFAULT_SHORT_RETRY_LIMIT 7 #define B43_DEFAULT_LONG_RETRY_LIMIT 4 +#define B43_PHY_TX_BADNESS_LIMIT 1000 + /* Max size of a security key */ #define B43_SEC_KEYSIZE 16 /* Security algorithms. */ @@ -542,6 +544,13 @@ struct b43_phy { u16 lofcal; u16 initval; //FIXME rename? + + /* OFDM address read/write caching for hardware auto-increment. */ + u16 ofdm_addr; + u8 ofdm_valid; /* 0: invalid, 1: read, 2: write */ + + /* PHY TX errors counter. */ + atomic_t txerr_cnt; }; /* Data structures for DMA transmission, per 80211 core. */ @@ -632,6 +641,8 @@ struct b43_wl { /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; + + bool radiotap_enabled; }; /* Pointers to the firmware data and meta information about it. */ diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index ef0075d..f84d063 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c @@ -352,7 +352,7 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf, struct b43_wldev *dev; struct b43_debugfs_fops *dfops; struct b43_dfs_file *dfile; - ssize_t ret; + ssize_t uninitialized_var(ret); char *buf; const size_t bufsize = 1024 * 128; const size_t buforder = get_order(bufsize); diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 5e8f8ac..f3552ac 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -165,7 +165,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring, addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) >> SSB_DMA_TRANSLATION_SHIFT; - addrhi |= ssb_dma_translation(ring->dev->dev); + addrhi |= (ssb_dma_translation(ring->dev->dev) << 1); if (slot == ring->nr_slots - 1) ctl0 |= B43_DMA64_DCTL0_DTABLEEND; if (start) @@ -426,9 +426,21 @@ static inline static int alloc_ringmemory(struct b43_dmaring *ring) { struct device *dev = ring->dev->dev->dev; - + gfp_t flags = GFP_KERNEL; + + /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K + * alignment and 8K buffers for 64-bit DMA with 8K alignment. Testing + * has shown that 4K is sufficient for the latter as long as the buffer + * does not cross an 8K boundary. + * + * For unknown reasons - possibly a hardware error - the BCM4311 rev + * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, + * which accounts for the GFP_DMA flag below. + */ + if (ring->dma64) + flags |= GFP_DMA; ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE, - &(ring->dmabase), GFP_KERNEL); + &(ring->dmabase), flags); if (!ring->descbase) { b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); return -ENOMEM; @@ -483,7 +495,7 @@ int b43_dmacontroller_rx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64) return 0; } -/* Reset the RX DMA channel */ +/* Reset the TX DMA channel */ int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base, int dma64) { int i; @@ -647,7 +659,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring) b43_dma_write(ring, B43_DMA64_TXRINGHI, ((ringbase >> 32) & ~SSB_DMA_TRANSLATION_MASK) - | trans); + | (trans << 1)); } else { u32 ringbase = (u32) (ring->dmabase); @@ -680,8 +692,9 @@ static int dmacontroller_setup(struct b43_dmaring *ring) b43_dma_write(ring, B43_DMA64_RXRINGHI, ((ringbase >> 32) & ~SSB_DMA_TRANSLATION_MASK) - | trans); - b43_dma_write(ring, B43_DMA64_RXINDEX, 200); + | (trans << 1)); + b43_dma_write(ring, B43_DMA64_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc64)); } else { u32 ringbase = (u32) (ring->dmabase); @@ -695,11 +708,12 @@ static int dmacontroller_setup(struct b43_dmaring *ring) b43_dma_write(ring, B43_DMA32_RXRING, (ringbase & ~SSB_DMA_TRANSLATION_MASK) | trans); - b43_dma_write(ring, B43_DMA32_RXINDEX, 200); + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc32)); } } - out: +out: return err; } diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 19e5885..9f33406 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c @@ -4,7 +4,7 @@ LED control Copyright (c) 2005 Martin Langer , - Copyright (c) 2005 Stefano Brivio + Copyright (c) 2005 Stefano Brivio Copyright (c) 2005-2007 Michael Buesch Copyright (c) 2005 Danny van Dyk Copyright (c) 2005 Andreas Jaggi @@ -187,10 +187,10 @@ void b43_leds_init(struct b43_wldev *dev) enum b43_led_behaviour behaviour; bool activelow; - sprom[0] = bus->sprom.r1.gpio0; - sprom[1] = bus->sprom.r1.gpio1; - sprom[2] = bus->sprom.r1.gpio2; - sprom[3] = bus->sprom.r1.gpio3; + sprom[0] = bus->sprom.gpio0; + sprom[1] = bus->sprom.gpio1; + sprom[2] = bus->sprom.gpio2; + sprom[3] = bus->sprom.gpio3; for (i = 0; i < 4; i++) { if (sprom[i] == 0xFF) { diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index b14a175..88f35e6 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c @@ -5,7 +5,7 @@ G PHY LO (LocalOscillator) Measuring and Control routines Copyright (c) 2005 Martin Langer , - Copyright (c) 2005, 2006 Stefano Brivio + Copyright (c) 2005, 2006 Stefano Brivio Copyright (c) 2005-2007 Michael Buesch Copyright (c) 2005, 2006 Danny van Dyk Copyright (c) 2005, 2006 Andreas Jaggi @@ -264,8 +264,8 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, rfover |= pga; rfover |= lna; rfover |= trsw_rx; - if ((dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) && - phy->rev > 6) + if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) + && phy->rev > 6) rfover |= B43_PHY_RFOVERVAL_EXTLNA; b43_phy_write(dev, B43_PHY_PGACTL, 0xE300); @@ -634,7 +634,7 @@ static void lo_measure_setup(struct b43_wldev *dev, & 0xFFFC); if (phy->type == B43_PHYTYPE_G) { if ((phy->rev >= 7) && - (sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { + (sprom->boardflags_lo & B43_BFL_EXTLNA)) { b43_phy_write(dev, B43_PHY_RFOVER, 0x933); } else { b43_phy_write(dev, B43_PHY_RFOVER, 0x133); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b45eecc..136545f 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3,7 +3,7 @@ Broadcom B43 wireless driver Copyright (c) 2005 Martin Langer - Copyright (c) 2005 Stefano Brivio + Copyright (c) 2005 Stefano Brivio Copyright (c) 2005, 2006 Michael Buesch Copyright (c) 2005 Danny van Dyk Copyright (c) 2005 Andreas Jaggi @@ -75,14 +75,6 @@ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames Preemption"); -static int modparam_short_retry = B43_DEFAULT_SHORT_RETRY_LIMIT; -module_param_named(short_retry, modparam_short_retry, int, 0444); -MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)"); - -static int modparam_long_retry = B43_DEFAULT_LONG_RETRY_LIMIT; -module_param_named(long_retry, modparam_long_retry, int, 0444); -MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); - static char modparam_fwpostfix[16]; module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444); MODULE_PARM_DESC(fwpostfix, "Postfix for the .fw files to load."); @@ -101,6 +93,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = { SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), + SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), SSB_DEVTABLE_END }; @@ -1402,8 +1395,17 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev) if (unlikely(reason & B43_IRQ_MAC_TXERR)) b43err(dev->wl, "MAC transmission error\n"); - if (unlikely(reason & B43_IRQ_PHY_TXERR)) + if (unlikely(reason & B43_IRQ_PHY_TXERR)) { b43err(dev->wl, "PHY transmission error\n"); + rmb(); + if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) { + atomic_set(&dev->phy.txerr_cnt, + B43_PHY_TX_BADNESS_LIMIT); + b43err(dev->wl, "Too many PHY TX errors, " + "restarting the controller\n"); + b43_controller_restart(dev, "PHY TX errors"); + } + } if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | B43_DMAIRQ_NONFATALMASK))) { @@ -1932,7 +1934,7 @@ static int b43_gpio_init(struct b43_wldev *dev) mask |= 0x0180; set |= 0x0180; } - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) | 0x0200); @@ -2264,6 +2266,12 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write16(dev, B43_MMIO_POWERUP_DELAY, dev->dev->bus->chipco.fast_pwrup_delay); + /* OFDM address caching. */ + phy->ofdm_valid = 0; + + /* PHY TX errors counter. */ + atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); + err = 0; b43dbg(dev->wl, "Chip initialized\n"); out: @@ -2297,7 +2305,7 @@ static void b43_periodic_every60sec(struct b43_wldev *dev) if (!b43_has_hardware_pctl(phy)) b43_lo_g_ctl_mark_all_unused(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) { b43_mac_suspend(dev); b43_calc_nrssi_slope(dev); if ((phy->radio_ver == 0x2050) && (phy->radio_rev == 8)) { @@ -2349,6 +2357,9 @@ static void b43_periodic_every15sec(struct b43_wldev *dev) } b43_phy_xmitpower(dev); //FIXME: unless scanning? //TODO for APHY (temperature?) + + atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); + wmb(); } static void do_periodic_work(struct b43_wldev *dev) @@ -2494,8 +2505,9 @@ static int b43_rng_init(struct b43_wl *wl) return err; } -static int b43_tx(struct ieee80211_hw *hw, - struct sk_buff *skb, struct ieee80211_tx_control *ctl) +static int b43_op_tx(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct ieee80211_tx_control *ctl) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -2513,21 +2525,21 @@ static int b43_tx(struct ieee80211_hw *hw, spin_unlock_irqrestore(&wl->irq_lock, flags); } else err = b43_dma_tx(dev, skb, ctl); - out: +out: if (unlikely(err)) return NETDEV_TX_BUSY; return NETDEV_TX_OK; } -static int b43_conf_tx(struct ieee80211_hw *hw, - int queue, - const struct ieee80211_tx_queue_params *params) +static int b43_op_conf_tx(struct ieee80211_hw *hw, + int queue, + const struct ieee80211_tx_queue_params *params) { return 0; } -static int b43_get_tx_stats(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats) +static int b43_op_get_tx_stats(struct ieee80211_hw *hw, + struct ieee80211_tx_queue_stats *stats) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -2545,12 +2557,12 @@ static int b43_get_tx_stats(struct ieee80211_hw *hw, err = 0; } spin_unlock_irqrestore(&wl->irq_lock, flags); - out: +out: return err; } -static int b43_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) +static int b43_op_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) { struct b43_wl *wl = hw_to_b43_wl(hw); unsigned long flags; @@ -2703,7 +2715,7 @@ static int b43_antenna_from_ieee80211(u8 antenna) } } -static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) +static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev; @@ -2767,6 +2779,8 @@ static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) b43_short_slot_timing_disable(dev); } + dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); + /* Adjust the desired TX power level. */ if (conf->power_level != 0) { if (conf->power_level != phy->power_level) { @@ -2808,23 +2822,30 @@ static int b43_dev_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) return err; } -static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, +static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, const u8 *local_addr, const u8 *addr, struct ieee80211_key_conf *key) { struct b43_wl *wl = hw_to_b43_wl(hw); - struct b43_wldev *dev = wl->current_dev; + struct b43_wldev *dev; unsigned long flags; u8 algorithm; u8 index; - int err = -EINVAL; + int err; DECLARE_MAC_BUF(mac); if (modparam_nohwcrypt) return -ENOSPC; /* User disabled HW-crypto */ - if (!dev) - return -ENODEV; + mutex_lock(&wl->mutex); + spin_lock_irqsave(&wl->irq_lock, flags); + + dev = wl->current_dev; + err = -ENODEV; + if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) + goto out_unlock; + + err = -EINVAL; switch (key->alg) { case ALG_WEP: if (key->keylen == 5) @@ -2840,20 +2861,11 @@ static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; default: B43_WARN_ON(1); - goto out; + goto out_unlock; } - index = (u8) (key->keyidx); if (index > 3) - goto out; - - mutex_lock(&wl->mutex); - spin_lock_irqsave(&wl->irq_lock, flags); - - if (b43_status(dev) < B43_STAT_INITIALIZED) { - err = -ENODEV; goto out_unlock; - } switch (cmd) { case SET_KEY: @@ -2899,7 +2911,6 @@ static int b43_dev_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, out_unlock: spin_unlock_irqrestore(&wl->irq_lock, flags); mutex_unlock(&wl->mutex); -out: if (!err) { b43dbg(wl, "%s hardware based encryption for keyidx: %d, " "mac: %s\n", @@ -2909,9 +2920,9 @@ out: return err; } -static void b43_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, unsigned int *fflags, - int mc_count, struct dev_addr_list *mc_list) +static void b43_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed, unsigned int *fflags, + int mc_count, struct dev_addr_list *mc_list) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -2946,8 +2957,9 @@ static void b43_configure_filter(struct ieee80211_hw *hw, spin_unlock_irqrestore(&wl->irq_lock, flags); } -static int b43_config_interface(struct ieee80211_hw *hw, - int if_id, struct ieee80211_if_conf *conf) +static int b43_op_config_interface(struct ieee80211_hw *hw, + int if_id, + struct ieee80211_if_conf *conf) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -3070,7 +3082,7 @@ static int b43_phy_versioning(struct b43_wldev *dev) unsupported = 1; break; case B43_PHYTYPE_G: - if (phy_rev > 8) + if (phy_rev > 9) unsupported = 1; break; default: @@ -3217,13 +3229,13 @@ static void b43_bluetooth_coext_enable(struct b43_wldev *dev) struct ssb_sprom *sprom = &dev->dev->bus->sprom; u32 hf; - if (!(sprom->r1.boardflags_lo & B43_BFL_BTCOEXIST)) + if (!(sprom->boardflags_lo & B43_BFL_BTCOEXIST)) return; if (dev->phy.type != B43_PHYTYPE_B && !dev->phy.gmode) return; hf = b43_hf_read(dev); - if (sprom->r1.boardflags_lo & B43_BFL_BTCMOD) + if (sprom->boardflags_lo & B43_BFL_BTCMOD) hf |= B43_HF_BTCOEXALT; else hf |= B43_HF_BTCOEX; @@ -3262,6 +3274,22 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) #endif /* CONFIG_SSB_DRIVER_PCICORE */ } +/* Write the short and long frame retry limit values. */ +static void b43_set_retry_limits(struct b43_wldev *dev, + unsigned int short_retry, + unsigned int long_retry) +{ + /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing + * the chip-internal counter. */ + short_retry = min(short_retry, (unsigned int)0xF); + long_retry = min(long_retry, (unsigned int)0xF); + + b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT, + short_retry); + b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT, + long_retry); +} + /* Shutdown a wireless core */ /* Locking: wl->mutex */ static void b43_wireless_core_exit(struct b43_wldev *dev) @@ -3341,7 +3369,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) hf |= B43_HF_SYMW; if (phy->rev == 1) hf |= B43_HF_GDCW; - if (sprom->r1.boardflags_lo & B43_BFL_PACTRL) + if (sprom->boardflags_lo & B43_BFL_PACTRL) hf |= B43_HF_OFDMPABOOST; } else if (phy->type == B43_PHYTYPE_B) { hf |= B43_HF_SYMW; @@ -3350,15 +3378,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) } b43_hf_write(dev, hf); - /* Short/Long Retry Limit. - * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing - * the chip-internal counter. - */ - tmp = limit_value(modparam_short_retry, 0, 0xF); - b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT, tmp); - tmp = limit_value(modparam_long_retry, 0, 0xF); - b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT, tmp); - + b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT, + B43_DEFAULT_LONG_RETRY_LIMIT); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_LFFBLIM, 2); @@ -3427,8 +3448,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) return err; } -static int b43_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +static int b43_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev; @@ -3467,8 +3488,8 @@ static int b43_add_interface(struct ieee80211_hw *hw, return err; } -static void b43_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +static void b43_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -3492,7 +3513,7 @@ static void b43_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&wl->mutex); } -static int b43_start(struct ieee80211_hw *hw) +static int b43_op_start(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -3523,7 +3544,7 @@ static int b43_start(struct ieee80211_hw *hw) return err; } -static void b43_stop(struct ieee80211_hw *hw) +static void b43_op_stop(struct ieee80211_hw *hw) { struct b43_wl *wl = hw_to_b43_wl(hw); struct b43_wldev *dev = wl->current_dev; @@ -3535,19 +3556,40 @@ static void b43_stop(struct ieee80211_hw *hw) mutex_unlock(&wl->mutex); } +static int b43_op_set_retry_limit(struct ieee80211_hw *hw, + u32 short_retry_limit, u32 long_retry_limit) +{ + struct b43_wl *wl = hw_to_b43_wl(hw); + struct b43_wldev *dev; + int err = 0; + + mutex_lock(&wl->mutex); + dev = wl->current_dev; + if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) { + err = -ENODEV; + goto out_unlock; + } + b43_set_retry_limits(dev, short_retry_limit, long_retry_limit); +out_unlock: + mutex_unlock(&wl->mutex); + + return err; +} + static const struct ieee80211_ops b43_hw_ops = { - .tx = b43_tx, - .conf_tx = b43_conf_tx, - .add_interface = b43_add_interface, - .remove_interface = b43_remove_interface, - .config = b43_dev_config, - .config_interface = b43_config_interface, - .configure_filter = b43_configure_filter, - .set_key = b43_dev_set_key, - .get_stats = b43_get_stats, - .get_tx_stats = b43_get_tx_stats, - .start = b43_start, - .stop = b43_stop, + .tx = b43_op_tx, + .conf_tx = b43_op_conf_tx, + .add_interface = b43_op_add_interface, + .remove_interface = b43_op_remove_interface, + .config = b43_op_config, + .config_interface = b43_op_config_interface, + .configure_filter = b43_op_configure_filter, + .set_key = b43_op_set_key, + .get_stats = b43_op_get_stats, + .get_tx_stats = b43_op_get_tx_stats, + .start = b43_op_start, + .stop = b43_op_stop, + .set_retry_limit = b43_op_set_retry_limit, }; /* Hard-reset the chip. Do not call this directly. @@ -3838,20 +3880,20 @@ static void b43_sprom_fixup(struct ssb_bus *bus) /* boardflags workarounds */ if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL && bus->chip_id == 0x4301 && bus->boardinfo.rev == 0x74) - bus->sprom.r1.boardflags_lo |= B43_BFL_BTCOEXIST; + bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST; if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) - bus->sprom.r1.boardflags_lo |= B43_BFL_PACTRL; + bus->sprom.boardflags_lo |= B43_BFL_PACTRL; /* Handle case when gain is not set in sprom */ - if (bus->sprom.r1.antenna_gain_a == 0xFF) - bus->sprom.r1.antenna_gain_a = 2; - if (bus->sprom.r1.antenna_gain_bg == 0xFF) - bus->sprom.r1.antenna_gain_bg = 2; + if (bus->sprom.antenna_gain_a == 0xFF) + bus->sprom.antenna_gain_a = 2; + if (bus->sprom.antenna_gain_bg == 0xFF) + bus->sprom.antenna_gain_bg = 2; /* Convert Antennagain values to Q5.2 */ - bus->sprom.r1.antenna_gain_a <<= 2; - bus->sprom.r1.antenna_gain_bg <<= 2; + bus->sprom.antenna_gain_a <<= 2; + bus->sprom.antenna_gain_bg <<= 2; } static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) @@ -3878,16 +3920,17 @@ static int b43_wireless_init(struct ssb_device *dev) } /* fill hw info */ - hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; + hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | + IEEE80211_HW_RX_INCLUDES_FCS; hw->max_signal = 100; hw->max_rssi = -110; hw->max_noise = -110; hw->queues = 1; /* FIXME: hardware has more queues */ SET_IEEE80211_DEV(hw, dev->dev); - if (is_valid_ether_addr(sprom->r1.et1mac)) - SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac); + if (is_valid_ether_addr(sprom->et1mac)) + SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); else - SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac); + SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); /* Get and initialize struct b43_wl */ wl = hw_to_b43_wl(hw); diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 284d17d..821b397 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h @@ -3,7 +3,7 @@ Broadcom B43 wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi diff --git a/drivers/net/wireless/b43/phy.c b/drivers/net/wireless/b43/phy.c index 7ff091e..facc01c 100644 --- a/drivers/net/wireless/b43/phy.c +++ b/drivers/net/wireless/b43/phy.c @@ -3,7 +3,7 @@ Broadcom B43 wireless driver Copyright (c) 2005 Martin Langer , - Copyright (c) 2005, 2006 Stefano Brivio + Copyright (c) 2005-2007 Stefano Brivio Copyright (c) 2005, 2006 Michael Buesch Copyright (c) 2005, 2006 Danny van Dyk Copyright (c) 2005, 2006 Andreas Jaggi @@ -34,6 +34,8 @@ #include "main.h" #include "tables.h" #include "lo.h" +#include "wa.h" + static const s8 b43_tssi2dbm_b_table[] = { 0x4D, 0x4C, 0x4B, 0x4A, @@ -303,8 +305,6 @@ void b43_phy_write(struct b43_wldev *dev, u16 offset, u16 val) b43_write16(dev, B43_MMIO_PHY_DATA, val); } -static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower); - /* Adjust the transmission power output (G-PHY) */ void b43_set_txpower_g(struct b43_wldev *dev, const struct b43_bbatt *bbatt, @@ -763,366 +763,96 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) b43_shm_clear_tssi(dev); } -static void b43_phy_agcsetup(struct b43_wldev *dev) -{ - struct b43_phy *phy = &dev->phy; - u16 offset = 0x0000; - - if (phy->rev == 1) - offset = 0x4C00; - - b43_ofdmtab_write16(dev, offset, 0, 0x00FE); - b43_ofdmtab_write16(dev, offset, 1, 0x000D); - b43_ofdmtab_write16(dev, offset, 2, 0x0013); - b43_ofdmtab_write16(dev, offset, 3, 0x0019); - - if (phy->rev == 1) { - b43_ofdmtab_write16(dev, 0x1800, 0, 0x2710); - b43_ofdmtab_write16(dev, 0x1801, 0, 0x9B83); - b43_ofdmtab_write16(dev, 0x1802, 0, 0x9B83); - b43_ofdmtab_write16(dev, 0x1803, 0, 0x0F8D); - b43_phy_write(dev, 0x0455, 0x0004); - } - - b43_phy_write(dev, 0x04A5, (b43_phy_read(dev, 0x04A5) - & 0x00FF) | 0x5700); - b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) - & 0xFF80) | 0x000F); - b43_phy_write(dev, 0x041A, (b43_phy_read(dev, 0x041A) - & 0xC07F) | 0x2B80); - b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) - & 0xF0FF) | 0x0300); - - b43_radio_write16(dev, 0x007A, b43_radio_read16(dev, 0x007A) - | 0x0008); - - b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) - & 0xFFF0) | 0x0008); - b43_phy_write(dev, 0x04A1, (b43_phy_read(dev, 0x04A1) - & 0xF0FF) | 0x0600); - b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) - & 0xF0FF) | 0x0700); - b43_phy_write(dev, 0x04A0, (b43_phy_read(dev, 0x04A0) - & 0xF0FF) | 0x0100); - - if (phy->rev == 1) { - b43_phy_write(dev, 0x04A2, (b43_phy_read(dev, 0x04A2) - & 0xFFF0) | 0x0007); - } - - b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) - & 0xFF00) | 0x001C); - b43_phy_write(dev, 0x0488, (b43_phy_read(dev, 0x0488) - & 0xC0FF) | 0x0200); - b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) - & 0xFF00) | 0x001C); - b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) - & 0xFF00) | 0x0020); - b43_phy_write(dev, 0x0489, (b43_phy_read(dev, 0x0489) - & 0xC0FF) | 0x0200); - b43_phy_write(dev, 0x0482, (b43_phy_read(dev, 0x0482) - & 0xFF00) | 0x002E); - b43_phy_write(dev, 0x0496, (b43_phy_read(dev, 0x0496) - & 0x00FF) | 0x1A00); - b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) - & 0xFF00) | 0x0028); - b43_phy_write(dev, 0x0481, (b43_phy_read(dev, 0x0481) - & 0x00FF) | 0x2C00); - - if (phy->rev == 1) { - b43_phy_write(dev, 0x0430, 0x092B); - b43_phy_write(dev, 0x041B, (b43_phy_read(dev, 0x041B) - & 0xFFE1) | 0x0002); - } else { - b43_phy_write(dev, 0x041B, b43_phy_read(dev, 0x041B) - & 0xFFE1); - b43_phy_write(dev, 0x041F, 0x287A); - b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) - & 0xFFF0) | 0x0004); - } - - if (phy->rev >= 6) { - b43_phy_write(dev, 0x0422, 0x287A); - b43_phy_write(dev, 0x0420, (b43_phy_read(dev, 0x0420) - & 0x0FFF) | 0x3000); - } - - b43_phy_write(dev, 0x04A8, (b43_phy_read(dev, 0x04A8) - & 0x8080) | 0x7874); - b43_phy_write(dev, 0x048E, 0x1C00); - - offset = 0x0800; - if (phy->rev == 1) { - offset = 0x5400; - b43_phy_write(dev, 0x04AB, (b43_phy_read(dev, 0x04AB) - & 0xF0FF) | 0x0600); - b43_phy_write(dev, 0x048B, 0x005E); - b43_phy_write(dev, 0x048C, (b43_phy_read(dev, 0x048C) - & 0xFF00) | 0x001E); - b43_phy_write(dev, 0x048D, 0x0002); - } - b43_ofdmtab_write16(dev, offset, 0, 0x00); - b43_ofdmtab_write16(dev, offset, 1, 0x07); - b43_ofdmtab_write16(dev, offset, 2, 0x10); - b43_ofdmtab_write16(dev, offset, 3, 0x1C); - - if (phy->rev >= 6) { - b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) - & 0xFFFC); - b43_phy_write(dev, 0x0426, b43_phy_read(dev, 0x0426) - & 0xEFFF); - } -} - -static void b43_phy_setupg(struct b43_wldev *dev) -{ - struct ssb_bus *bus = dev->dev->bus; - struct b43_phy *phy = &dev->phy; - u16 i; - - B43_WARN_ON(phy->type != B43_PHYTYPE_G); - if (phy->rev == 1) { - b43_phy_write(dev, 0x0406, 0x4F19); - b43_phy_write(dev, B43_PHY_G_CRS, - (b43_phy_read(dev, B43_PHY_G_CRS) & 0xFC3F) | - 0x0340); - b43_phy_write(dev, 0x042C, 0x005A); - b43_phy_write(dev, 0x0427, 0x001A); - - for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5800, i, - b43_tab_finefreqg[i]); - for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg1[i]); - for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x2000, i, b43_tab_rotor[i]); - } else { - /* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */ - b43_nrssi_hw_write(dev, 0xBA98, (s16) 0x7654); - - if (phy->rev == 2) { - b43_phy_write(dev, 0x04C0, 0x1861); - b43_phy_write(dev, 0x04C1, 0x0271); - } else if (phy->rev > 2) { - b43_phy_write(dev, 0x04C0, 0x0098); - b43_phy_write(dev, 0x04C1, 0x0070); - b43_phy_write(dev, 0x04C9, 0x0080); - } - b43_phy_write(dev, 0x042B, b43_phy_read(dev, 0x042B) | 0x800); - - for (i = 0; i < 64; i++) - b43_ofdmtab_write16(dev, 0x4000, i, i); - for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noiseg2[i]); - } - - if (phy->rev <= 2) - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg1[i]); - else if ((phy->rev >= 7) && (b43_phy_read(dev, 0x0449) & 0x0200)) - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg3[i]); - else - for (i = 0; i < B43_TAB_NOISESCALEG_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1400, i, - b43_tab_noisescaleg2[i]); - - if (phy->rev == 2) - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr1[i]); - else if ((phy->rev > 2) && (phy->rev <= 8)) - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr2[i]); - - if (phy->rev == 1) { - for (i = 0; i < B43_TAB_RETARD_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); - for (i = 4; i < 20; i++) - b43_ofdmtab_write16(dev, 0x5400, i, 0x0020); - b43_phy_agcsetup(dev); - - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306) && - (bus->boardinfo.rev == 0x17)) - return; - - b43_ofdmtab_write16(dev, 0x5001, 0, 0x0002); - b43_ofdmtab_write16(dev, 0x5002, 0, 0x0001); - } else { - for (i = 0; i < 0x20; i++) - b43_ofdmtab_write16(dev, 0x1000, i, 0x0820); - b43_phy_agcsetup(dev); - b43_phy_read(dev, 0x0400); /* dummy read */ - b43_phy_write(dev, 0x0403, 0x1000); - b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); - - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - (bus->boardinfo.type == SSB_BOARD_BU4306) && - (bus->boardinfo.rev == 0x17)) - return; - - b43_ofdmtab_write16(dev, 0x0401, 0, 0x0002); - b43_ofdmtab_write16(dev, 0x0402, 0, 0x0001); - } -} - -/* Initialize the noisescaletable for APHY */ -static void b43_phy_init_noisescaletbl(struct b43_wldev *dev) +static void b43_phy_rssiagc(struct b43_wldev *dev, u8 enable) { - struct b43_phy *phy = &dev->phy; int i; - for (i = 0; i < 12; i++) { - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); + if (dev->phy.rev < 3) { + if (enable) + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { + b43_ofdmtab_write16(dev, + B43_OFDMTAB_LNAHPFGAIN1, i, 0xFFF8); + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, 0xFFF8); + } else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); - } - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6700); - else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2300); - for (i = 0; i < 11; i++) { - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x6767); + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) { + b43_ofdmtab_write16(dev, + B43_OFDMTAB_LNAHPFGAIN1, i, b43_tab_rssiagc1[i]); + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc1[i]); + } + } else { + if (enable) + for (i = 0; i < B43_TAB_RSSIAGC1_SIZE; i++) + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, 0x0820); else - b43_ofdmtab_write16(dev, 0x1400, i, 0x2323); + for (i = 0; i < B43_TAB_RSSIAGC2_SIZE; i++) + b43_ofdmtab_write16(dev, + B43_OFDMTAB_WRSSI, i, b43_tab_rssiagc2[i]); } - if (phy->rev == 2) - b43_ofdmtab_write16(dev, 0x1400, i, 0x0067); - else - b43_ofdmtab_write16(dev, 0x1400, i, 0x0023); } -static void b43_phy_setupa(struct b43_wldev *dev) +static void b43_phy_ww(struct b43_wldev *dev) { - struct b43_phy *phy = &dev->phy; - u16 i; - - B43_WARN_ON(phy->type != B43_PHYTYPE_A); - switch (phy->rev) { - case 2: - b43_phy_write(dev, 0x008E, 0x3800); - b43_phy_write(dev, 0x0035, 0x03FF); - b43_phy_write(dev, 0x0036, 0x0400); - - b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); - - b43_phy_write(dev, 0x001C, 0x0FF9); - b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); - b43_ofdmtab_write16(dev, 0x3C0C, 0, 0x07BF); - b43_radio_write16(dev, 0x0002, 0x07BF); - - b43_phy_write(dev, 0x0024, 0x4680); - b43_phy_write(dev, 0x0020, 0x0003); - b43_phy_write(dev, 0x001D, 0x0F40); - b43_phy_write(dev, 0x001F, 0x1C00); - - b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) - & 0x00FF) | 0x0400); - b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) - & 0xFBFF); - b43_phy_write(dev, 0x008E, 0x58C1); - - b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); - b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); - - b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 1, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 2, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 3, 0x0013); - b43_ofdmtab_write16(dev, 0x0000, 4, 0x0015); - b43_ofdmtab_write16(dev, 0x0000, 5, 0x0015); - b43_ofdmtab_write16(dev, 0x0000, 6, 0x0019); - - b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); - - for (i = 0; i < 16; i++) - b43_ofdmtab_write16(dev, 0x4000, i, (0x8 + i) & 0x000F); - - b43_ofdmtab_write16(dev, 0x3003, 0, 0x1044); - b43_ofdmtab_write16(dev, 0x3004, 0, 0x7201); - b43_ofdmtab_write16(dev, 0x3006, 0, 0x0040); - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) & - 0x0010) | 0x0008); - - for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) - b43_ofdmtab_write16(dev, 0x5800, i, - b43_tab_finefreqa[i]); - for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea2[i]); - for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2000, i, b43_tab_rotor[i]); - b43_phy_init_noisescaletbl(dev); - for (i = 0; i < B43_TAB_RETARD_SIZE; i++) - b43_ofdmtab_write32(dev, 0x2400, i, b43_tab_retard[i]); - break; - case 3: - for (i = 0; i < 64; i++) - b43_ofdmtab_write16(dev, 0x4000, i, i); - - b43_ofdmtab_write16(dev, 0x3807, 0, 0x0051); - - b43_phy_write(dev, 0x001C, 0x0FF9); - b43_phy_write(dev, 0x0020, b43_phy_read(dev, 0x0020) & 0xFF0F); - b43_radio_write16(dev, 0x0002, 0x07BF); - - b43_phy_write(dev, 0x0024, 0x4680); - b43_phy_write(dev, 0x0020, 0x0003); - b43_phy_write(dev, 0x001D, 0x0F40); - b43_phy_write(dev, 0x001F, 0x1C00); - b43_phy_write(dev, 0x002A, (b43_phy_read(dev, 0x002A) - & 0x00FF) | 0x0400); - - b43_ofdmtab_write16(dev, 0x3000, 1, - (b43_ofdmtab_read16(dev, 0x3000, 1) - & 0x0010) | 0x0008); - for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) { - b43_ofdmtab_write16(dev, 0x1800, i, b43_tab_noisea3[i]); - } - b43_phy_init_noisescaletbl(dev); - for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { - b43_ofdmtab_write16(dev, 0x5000, i, - b43_tab_sigmasqr1[i]); - } - - b43_phy_write(dev, 0x0003, 0x1808); - - b43_ofdmtab_write16(dev, 0x0803, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x0804, 0, 0x001F); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x002A); - b43_ofdmtab_write16(dev, 0x0805, 0, 0x0030); - b43_ofdmtab_write16(dev, 0x0807, 0, 0x003A); - - b43_ofdmtab_write16(dev, 0x0000, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0001, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0002, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0003, 0, 0x0013); - b43_ofdmtab_write16(dev, 0x0004, 0, 0x0015); - b43_ofdmtab_write16(dev, 0x0005, 0, 0x0015); - b43_ofdmtab_write16(dev, 0x0006, 0, 0x0019); - - b43_ofdmtab_write16(dev, 0x0404, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0405, 0, 0x0003); - b43_ofdmtab_write16(dev, 0x0406, 0, 0x0007); + u16 b, curr_s, best_s = 0xFFFF; + int i; - b43_ofdmtab_write16(dev, 0x3C02, 0, 0x000F); - b43_ofdmtab_write16(dev, 0x3C03, 0, 0x0014); - break; - default: - B43_WARN_ON(1); - } + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) & ~B43_PHY_CRS0_EN); + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + b43_phy_read(dev, B43_PHY_OFDM(0x1B)) | 0x1000); + b43_phy_write(dev, B43_PHY_OFDM(0x82), + (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & 0xF0FF) | 0x0300); + b43_radio_write16(dev, 0x0009, + b43_radio_read16(dev, 0x0009) | 0x0080); + b43_radio_write16(dev, 0x0012, + (b43_radio_read16(dev, 0x0012) & 0xFFFC) | 0x0002); + b43_wa_initgains(dev); + b43_phy_write(dev, B43_PHY_OFDM(0xBA), 0x3ED5); + b = b43_phy_read(dev, B43_PHY_PWRDOWN); + b43_phy_write(dev, B43_PHY_PWRDOWN, (b & 0xFFF8) | 0x0005); + b43_radio_write16(dev, 0x0004, + b43_radio_read16(dev, 0x0004) | 0x0004); + for (i = 0x10; i <= 0x20; i++) { + b43_radio_write16(dev, 0x0013, i); + curr_s = b43_phy_read(dev, B43_PHY_OTABLEQ) & 0x00FF; + if (!curr_s) { + best_s = 0x0000; + break; + } else if (curr_s >= 0x0080) + curr_s = 0x0100 - curr_s; + if (curr_s < best_s) + best_s = curr_s; + } + b43_phy_write(dev, B43_PHY_PWRDOWN, b); + b43_radio_write16(dev, 0x0004, + b43_radio_read16(dev, 0x0004) & 0xFFFB); + b43_radio_write16(dev, 0x0013, best_s); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 0xFFEC); + b43_phy_write(dev, B43_PHY_OFDM(0xB7), 0x1E80); + b43_phy_write(dev, B43_PHY_OFDM(0xB6), 0x1C00); + b43_phy_write(dev, B43_PHY_OFDM(0xB5), 0x0EC0); + b43_phy_write(dev, B43_PHY_OFDM(0xB2), 0x00C0); + b43_phy_write(dev, B43_PHY_OFDM(0xB9), 0x1FFF); + b43_phy_write(dev, B43_PHY_OFDM(0xBB), + (b43_phy_read(dev, B43_PHY_OFDM(0xBB)) & 0xF000) | 0x0053); + b43_phy_write(dev, B43_PHY_OFDM61, + (b43_phy_read(dev, B43_PHY_OFDM61 & 0xFE1F)) | 0x0120); + b43_phy_write(dev, B43_PHY_OFDM(0x13), + (b43_phy_read(dev, B43_PHY_OFDM(0x13)) & 0x0FFF) | 0x3000); + b43_phy_write(dev, B43_PHY_OFDM(0x14), + (b43_phy_read(dev, B43_PHY_OFDM(0x14)) & 0x0FFF) | 0x3000); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 6, 0x0017); + for (i = 0; i < 6; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, i, 0x000F); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0D, 0x000E); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0E, 0x0011); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0x0F, 0x0013); + b43_phy_write(dev, B43_PHY_OFDM(0x33), 0x5030); + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); } /* Initialize APHY. This is also called for the GPHY in some cases. */ @@ -1130,64 +860,54 @@ static void b43_phy_inita(struct b43_wldev *dev) { struct ssb_bus *bus = dev->dev->bus; struct b43_phy *phy = &dev->phy; - u16 tval; might_sleep(); - if (phy->type == B43_PHYTYPE_A) { - b43_phy_setupa(dev); - } else { - b43_phy_setupg(dev); - if (phy->gmode && - (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL)) - b43_phy_write(dev, 0x046E, 0x03CF); - return; + if (phy->rev >= 6) { + if (phy->type == B43_PHYTYPE_A) + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x1000); + if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) + b43_phy_write(dev, B43_PHY_ENCORE, + b43_phy_read(dev, B43_PHY_ENCORE) | 0x0010); + else + b43_phy_write(dev, B43_PHY_ENCORE, + b43_phy_read(dev, B43_PHY_ENCORE) & ~0x1010); } - b43_phy_write(dev, B43_PHY_A_CRS, - (b43_phy_read(dev, B43_PHY_A_CRS) & 0xF83C) | 0x0340); - b43_phy_write(dev, 0x0034, 0x0001); + b43_wa_all(dev); - //TODO: RSSI AGC - b43_phy_write(dev, B43_PHY_A_CRS, - b43_phy_read(dev, B43_PHY_A_CRS) | (1 << 14)); - b43_radio_init2060(dev); + if (phy->type == B43_PHYTYPE_A) { + if (phy->gmode && (phy->rev < 3)) + b43_phy_write(dev, 0x0034, + b43_phy_read(dev, 0x0034) | 0x0001); + b43_phy_rssiagc(dev, 0); - if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && - ((bus->boardinfo.type == SSB_BOARD_BU4306) || - (bus->boardinfo.type == SSB_BOARD_BU4309))) { - if (phy->lofcal == 0xFFFF) { - //TODO: LOF Cal - b43_radio_set_tx_iq(dev); - } else - b43_radio_write16(dev, 0x001E, phy->lofcal); - } + b43_phy_write(dev, B43_PHY_CRS0, + b43_phy_read(dev, B43_PHY_CRS0) | B43_PHY_CRS0_EN); - b43_phy_write(dev, 0x007A, 0xF111); + b43_radio_init2060(dev); - if (phy->cur_idle_tssi == 0) { - b43_radio_write16(dev, 0x0019, 0x0000); - b43_radio_write16(dev, 0x0017, 0x0020); - - tval = b43_ofdmtab_read16(dev, 0x3001, 0); - if (phy->rev == 1) { - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) - & 0xFF87) - | 0x0058); - } else { - b43_ofdmtab_write16(dev, 0x3001, 0, - (b43_ofdmtab_read16(dev, 0x3001, 0) - & 0xFFC3) - | 0x002C); + if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && + ((bus->boardinfo.type == SSB_BOARD_BU4306) || + (bus->boardinfo.type == SSB_BOARD_BU4309))) { + ; //TODO: A PHY LO } - b43_dummy_transmission(dev); - phy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_A_PCTL); - b43_ofdmtab_write16(dev, 0x3001, 0, tval); - b43_radio_set_txpower_a(dev, 0x0018); + if (phy->rev >= 3) + b43_phy_ww(dev); + + hardware_pctl_init_aphy(dev); + + //TODO: radar detection + } + + if ((phy->type == B43_PHYTYPE_G) && + (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { + b43_phy_write(dev, B43_PHY_OFDM(0x6E), + (b43_phy_read(dev, B43_PHY_OFDM(0x6E)) + & 0xE000) | 0x3CF); } - b43_shm_clear_tssi(dev); } static void b43_phy_initb2(struct b43_wldev *dev) @@ -1286,7 +1006,7 @@ static void b43_phy_initb4(struct b43_wldev *dev) if (phy->radio_ver == 0x2050) b43_phy_write(dev, 0x002A, 0x88C2); b43_set_txpower_g(dev, &phy->bbatt, &phy->rfatt, phy->tx_control); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) { b43_calc_nrssi_slope(dev); b43_calc_nrssi_threshold(dev); } @@ -1433,7 +1153,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_radio_write16(dev, 0x5A, 0x88); b43_radio_write16(dev, 0x5B, 0x6B); b43_radio_write16(dev, 0x5C, 0x0F); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_ALTIQ) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { b43_radio_write16(dev, 0x5D, 0xFA); b43_radio_write16(dev, 0x5E, 0xD8); } else { @@ -1525,7 +1245,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) b43_phy_write(dev, 0x0062, 0x0007); b43_radio_init2050(dev); b43_lo_g_measure(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI) { b43_calc_nrssi_slope(dev); b43_calc_nrssi_threshold(dev); } @@ -1645,7 +1365,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_RFOVERVAL, b43_phy_read(dev, B43_PHY_RFOVERVAL) & 0xCFFF); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) { + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { if (phy->rev >= 7) { b43_phy_write(dev, B43_PHY_RFOVER, b43_phy_read(dev, B43_PHY_RFOVER) @@ -1812,7 +1532,7 @@ static void b43_phy_initg(struct b43_wldev *dev) & 0x0FFF) | (phy->lo_control-> tx_bias << 12)); } - if (dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_PACTRL) + if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x8075); else b43_phy_write(dev, B43_PHY_BASE(0x2E), 0x807F); @@ -1826,7 +1546,7 @@ static void b43_phy_initg(struct b43_wldev *dev) b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); } - if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) { + if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. @@ -2036,16 +1756,15 @@ void b43_phy_xmitpower(struct b43_wldev *dev) estimated_pwr = b43_phy_estimate_power_out(dev, average); - max_pwr = dev->dev->bus->sprom.r1.maxpwr_bg; - if ((dev->dev->bus->sprom.r1. - boardflags_lo & B43_BFL_PACTRL) - && (phy->type == B43_PHYTYPE_G)) + max_pwr = dev->dev->bus->sprom.maxpwr_bg; + if ((dev->dev->bus->sprom.boardflags_lo + & B43_BFL_PACTRL) && (phy->type == B43_PHYTYPE_G)) max_pwr -= 0x3; if (unlikely(max_pwr <= 0)) { b43warn(dev->wl, "Invalid max-TX-power value in SPROM.\n"); max_pwr = 60; /* fake it */ - dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr; + dev->dev->bus->sprom.maxpwr_bg = max_pwr; } /*TODO: @@ -2103,7 +1822,7 @@ void b43_phy_xmitpower(struct b43_wldev *dev) B43_TXCTL_TXMIX; rfatt += 2; bbatt += 2; - } else if (dev->dev->bus->sprom.r1. + } else if (dev->dev->bus->sprom. boardflags_lo & B43_BFL_PACTRL) { bbatt += 4 * (rfatt - 2); @@ -2179,13 +1898,13 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev) s8 *dyn_tssi2dbm; if (phy->type == B43_PHYTYPE_A) { - pab0 = (s16) (dev->dev->bus->sprom.r1.pa1b0); - pab1 = (s16) (dev->dev->bus->sprom.r1.pa1b1); - pab2 = (s16) (dev->dev->bus->sprom.r1.pa1b2); + pab0 = (s16) (dev->dev->bus->sprom.pa1b0); + pab1 = (s16) (dev->dev->bus->sprom.pa1b1); + pab2 = (s16) (dev->dev->bus->sprom.pa1b2); } else { - pab0 = (s16) (dev->dev->bus->sprom.r1.pa0b0); - pab1 = (s16) (dev->dev->bus->sprom.r1.pa0b1); - pab2 = (s16) (dev->dev->bus->sprom.r1.pa0b2); + pab0 = (s16) (dev->dev->bus->sprom.pa0b0); + pab1 = (s16) (dev->dev->bus->sprom.pa0b1); + pab2 = (s16) (dev->dev->bus->sprom.pa0b2); } if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) { @@ -2198,17 +1917,17 @@ int b43_phy_init_tssi2dbm_table(struct b43_wldev *dev) pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ if (phy->type == B43_PHYTYPE_A) { - if ((s8) dev->dev->bus->sprom.r1.itssi_a != 0 && - (s8) dev->dev->bus->sprom.r1.itssi_a != -1) + if ((s8) dev->dev->bus->sprom.itssi_a != 0 && + (s8) dev->dev->bus->sprom.itssi_a != -1) phy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.r1.itssi_a); + (s8) (dev->dev->bus->sprom.itssi_a); else phy->tgt_idle_tssi = 62; } else { - if ((s8) dev->dev->bus->sprom.r1.itssi_bg != 0 && - (s8) dev->dev->bus->sprom.r1.itssi_bg != -1) + if ((s8) dev->dev->bus->sprom.itssi_bg != 0 && + (s8) dev->dev->bus->sprom.itssi_bg != -1) phy->tgt_idle_tssi = - (s8) (dev->dev->bus->sprom.r1.itssi_bg); + (s8) (dev->dev->bus->sprom.itssi_bg); else phy->tgt_idle_tssi = 62; } @@ -3114,7 +2833,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) if (phy->radio_ver != 0x2050) return; if (! - (dev->dev->bus->sprom.r1. + (dev->dev->bus->sprom. boardflags_lo & B43_BFL_RSSI)) return; @@ -3145,7 +2864,7 @@ void b43_calc_nrssi_threshold(struct b43_wldev *dev) } case B43_PHYTYPE_G: if (!phy->gmode || - !(dev->dev->bus->sprom.r1.boardflags_lo & B43_BFL_RSSI)) { + !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { tmp16 = b43_nrssi_hw_read(dev, 0x20); if (tmp16 >= 0x20) tmp16 -= 0x40; @@ -3667,7 +3386,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, } if ((phy->rev < 7) || - !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { + !(sprom->boardflags_lo & B43_BFL_EXTLNA)) { if (phy_register == B43_PHY_RFOVER) { return 0x1B3; } else if (phy_register == B43_PHY_RFOVERVAL) { @@ -3707,7 +3426,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, } } else { if ((phy->rev < 7) || - !(sprom->r1.boardflags_lo & B43_BFL_EXTLNA)) { + !(sprom->boardflags_lo & B43_BFL_EXTLNA)) { if (phy_register == B43_PHY_RFOVER) { return 0x1B3; } else if (phy_register == B43_PHY_RFOVERVAL) { @@ -4186,7 +3905,7 @@ int b43_radio_selectchannel(struct b43_wldev *dev, b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); if (channel == 14) { - if (dev->dev->bus->sprom.r1.country_code == + if (dev->dev->bus->sprom.country_code == SSB_SPROM1CCODE_JAPAN) b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_ACPR); @@ -4210,103 +3929,6 @@ int b43_radio_selectchannel(struct b43_wldev *dev, return 0; } -/* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */ -static u16 b43_get_txgain_base_band(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 54) - ret = 2; - else if (txpower >= 49) - ret = 4; - else if (txpower >= 44) - ret = 5; - else - ret = 6; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */ -static u16 b43_get_txgain_freq_power_amp(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 32) - ret = 0; - else if (txpower >= 25) - ret = 1; - else if (txpower >= 20) - ret = 2; - else if (txpower >= 12) - ret = 3; - else - ret = 4; - - return ret; -} - -/* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */ -static u16 b43_get_txgain_dac(u16 txpower) -{ - u16 ret; - - B43_WARN_ON(txpower > 63); - - if (txpower >= 54) - ret = txpower - 53; - else if (txpower >= 49) - ret = txpower - 42; - else if (txpower >= 44) - ret = txpower - 37; - else if (txpower >= 32) - ret = txpower - 32; - else if (txpower >= 25) - ret = txpower - 20; - else if (txpower >= 20) - ret = txpower - 13; - else if (txpower >= 12) - ret = txpower - 8; - else - ret = txpower; - - return ret; -} - -static void b43_radio_set_txpower_a(struct b43_wldev *dev, u16 txpower) -{ - struct b43_phy *phy = &dev->phy; - u16 pamp, base, dac, t; - - txpower = limit_value(txpower, 0, 63); - - pamp = b43_get_txgain_freq_power_amp(txpower); - pamp <<= 5; - pamp &= 0x00E0; - b43_phy_write(dev, 0x0019, pamp); - - base = b43_get_txgain_base_band(txpower); - base &= 0x000F; - b43_phy_write(dev, 0x0017, base | 0x0020); - - t = b43_ofdmtab_read16(dev, 0x3000, 1); - t &= 0x0007; - - dac = b43_get_txgain_dac(txpower); - dac <<= 3; - dac |= t; - - b43_ofdmtab_write16(dev, 0x3000, 1, dac); - - phy->txpwr_offset = txpower; - - //TODO: FuncPlaceholder (Adjust BB loft cancel) -} - void b43_radio_turn_on(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; diff --git a/drivers/net/wireless/b43/phy.h b/drivers/net/wireless/b43/phy.h index c64d745..1c7eac2 100644 --- a/drivers/net/wireless/b43/phy.h +++ b/drivers/net/wireless/b43/phy.h @@ -27,8 +27,11 @@ struct b43_phy; #define B43_PHY_PWRDOWN B43_PHY_OFDM(0x03) /* Powerdown */ #define B43_PHY_CRSTHRES1 B43_PHY_OFDM(0x06) /* CRS Threshold 1 */ #define B43_PHY_LNAHPFCTL B43_PHY_OFDM(0x1C) /* LNA/HPF control */ +#define B43_PHY_LPFGAINCTL B43_PHY_OFDM(0x20) /* LPF Gain control */ #define B43_PHY_ADIVRELATED B43_PHY_OFDM(0x27) /* FIXME rename */ #define B43_PHY_CRS0 B43_PHY_OFDM(0x29) +#define B43_PHY_CRS0_EN 0x4000 +#define B43_PHY_PEAK_COUNT B43_PHY_OFDM(0x30) #define B43_PHY_ANTDWELL B43_PHY_OFDM(0x2B) /* Antenna dwell */ #define B43_PHY_ANTDWELL_AUTODIV1 0x0100 /* Automatic RX diversity start antenna */ #define B43_PHY_ENCORE B43_PHY_OFDM(0x49) /* "Encore" (RangeMax / BroadRange) */ @@ -37,6 +40,7 @@ struct b43_phy; #define B43_PHY_OFDM61 B43_PHY_OFDM(0x61) /* FIXME rename */ #define B43_PHY_OFDM61_10 0x0010 /* FIXME rename */ #define B43_PHY_IQBAL B43_PHY_OFDM(0x69) /* I/Q balance */ +#define B43_PHY_BBTXDC_BIAS B43_PHY_OFDM(0x6B) /* Baseband TX DC bias */ #define B43_PHY_OTABLECTL B43_PHY_OFDM(0x72) /* OFDM table control (see below) */ #define B43_PHY_OTABLEOFF 0x03FF /* OFDM table offset (see below) */ #define B43_PHY_OTABLENR 0xFC00 /* OFDM table number (see below) */ @@ -44,6 +48,9 @@ struct b43_phy; #define B43_PHY_OTABLEI B43_PHY_OFDM(0x73) /* OFDM table data I */ #define B43_PHY_OTABLEQ B43_PHY_OFDM(0x74) /* OFDM table data Q */ #define B43_PHY_HPWR_TSSICTL B43_PHY_OFDM(0x78) /* Hardware power TSSI control */ +#define B43_PHY_ADCCTL B43_PHY_OFDM(0x7A) /* ADC control */ +#define B43_PHY_IDLE_TSSI B43_PHY_OFDM(0x7B) +#define B43_PHY_A_TEMP_SENSE B43_PHY_OFDM(0x7C) /* A PHY temperature sense */ #define B43_PHY_NRSSITHRES B43_PHY_OFDM(0x8A) /* NRSSI threshold */ #define B43_PHY_ANTWRSETT B43_PHY_OFDM(0x8C) /* Antenna WR settle */ #define B43_PHY_ANTWRSETT_ARXDIV 0x2000 /* Automatic RX diversity enabled */ @@ -54,6 +61,8 @@ struct b43_phy; #define B43_PHY_N1N2GAIN B43_PHY_OFDM(0xA2) #define B43_PHY_CLIPTHRES B43_PHY_OFDM(0xA3) #define B43_PHY_CLIPN1P2THRES B43_PHY_OFDM(0xA4) +#define B43_PHY_CCKSHIFTBITS_WA B43_PHY_OFDM(0xA5) /* CCK shiftbits workaround, FIXME rename */ +#define B43_PHY_CCKSHIFTBITS B43_PHY_OFDM(0xA7) /* FIXME rename */ #define B43_PHY_DIVSRCHIDX B43_PHY_OFDM(0xA8) /* Divider search gain/index */ #define B43_PHY_CLIPP2THRES B43_PHY_OFDM(0xA9) #define B43_PHY_CLIPP3THRES B43_PHY_OFDM(0xAA) @@ -125,13 +134,14 @@ struct b43_phy; #define B43_OFDMTAB_DC B43_OFDMTAB(0x0E, 7) #define B43_OFDMTAB_PWRDYN2 B43_OFDMTAB(0x0E, 12) #define B43_OFDMTAB_LNAGAIN B43_OFDMTAB(0x0E, 13) -//TODO +#define B43_OFDMTAB_UNKNOWN_0F B43_OFDMTAB(0x0F, 0) //TODO rename +#define B43_OFDMTAB_UNKNOWN_APHY B43_OFDMTAB(0x0F, 7) //TODO rename #define B43_OFDMTAB_LPFGAIN B43_OFDMTAB(0x0F, 12) #define B43_OFDMTAB_RSSI B43_OFDMTAB(0x10, 0) -//TODO +#define B43_OFDMTAB_UNKNOWN_11 B43_OFDMTAB(0x11, 4) //TODO rename #define B43_OFDMTAB_AGC1_R1 B43_OFDMTAB(0x13, 0) -#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO rename -#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 1) +#define B43_OFDMTAB_GAINX_R1 B43_OFDMTAB(0x14, 0) //TODO remove! +#define B43_OFDMTAB_MINSIGSQ B43_OFDMTAB(0x14, 0) #define B43_OFDMTAB_AGC3_R1 B43_OFDMTAB(0x15, 0) #define B43_OFDMTAB_WRSSI_R1 B43_OFDMTAB(0x15, 4) #define B43_OFDMTAB_TSSI B43_OFDMTAB(0x15, 0) diff --git a/drivers/net/wireless/b43/tables.c b/drivers/net/wireless/b43/tables.c index 15a8718..be9c7eb 100644 --- a/drivers/net/wireless/b43/tables.c +++ b/drivers/net/wireless/b43/tables.c @@ -3,7 +3,7 @@ Broadcom B43 wireless driver Copyright (c) 2005 Martin Langer , - Copyright (c) 2005 Stefano Brivio + Copyright (c) 2005-2007 Stefano Brivio Copyright (c) 2006, 2006 Michael Buesch Copyright (c) 2005 Danny van Dyk Copyright (c) 2005 Andreas Jaggi @@ -229,7 +229,7 @@ const u16 b43_tab_noisea2[] = { }; const u16 b43_tab_noisea3[] = { - 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, + 0x5E5E, 0x5E5E, 0x5E5E, 0x3F48, 0x4C4C, 0x4C4C, 0x4C4C, 0x2D36, }; @@ -243,6 +243,26 @@ const u16 b43_tab_noiseg2[] = { 0x0000, 0x0000, 0x0000, 0x0000, }; +const u16 b43_tab_noisescalea2[] = { + 0x6767, 0x6767, 0x6767, 0x6767, /* 0 */ + 0x6767, 0x6767, 0x6767, 0x6767, + 0x6767, 0x6767, 0x6767, 0x6767, + 0x6767, 0x6700, 0x6767, 0x6767, + 0x6767, 0x6767, 0x6767, 0x6767, /* 16 */ + 0x6767, 0x6767, 0x6767, 0x6767, + 0x6767, 0x6767, 0x0067, +}; + +const u16 b43_tab_noisescalea3[] = { + 0x2323, 0x2323, 0x2323, 0x2323, /* 0 */ + 0x2323, 0x2323, 0x2323, 0x2323, + 0x2323, 0x2323, 0x2323, 0x2323, + 0x2323, 0x2300, 0x2323, 0x2323, + 0x2323, 0x2323, 0x2323, 0x2323, /* 16 */ + 0x2323, 0x2323, 0x2323, 0x2323, + 0x2323, 0x2323, 0x0023, +}; + const u16 b43_tab_noisescaleg1[] = { 0x6C77, 0x5162, 0x3B40, 0x3335, /* 0 */ 0x2F2D, 0x2A2A, 0x2527, 0x1F21, @@ -254,7 +274,7 @@ const u16 b43_tab_noisescaleg1[] = { }; const u16 b43_tab_noisescaleg2[] = { - 0xD8DD, 0xCBD4, 0xBCC0, 0XB6B7, /* 0 */ + 0xD8DD, 0xCBD4, 0xBCC0, 0xB6B7, /* 0 */ 0xB2B0, 0xADAD, 0xA7A9, 0x9FA1, 0x969B, 0x9195, 0x8F8F, 0x8A8A, 0x8A8A, 0x8A00, 0x8A8A, 0x8F8A, @@ -307,6 +327,28 @@ const u16 b43_tab_sigmasqr2[] = { 0x00DE, }; +const u16 b43_tab_rssiagc1[] = { + 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, /* 0 */ + 0xFFF8, 0xFFF9, 0xFFFC, 0xFFFE, + 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, + 0xFFF8, 0xFFF8, 0xFFF8, 0xFFF8, +}; + +const u16 b43_tab_rssiagc2[] = { + 0x0820, 0x0820, 0x0920, 0x0C38, /* 0 */ + 0x0820, 0x0820, 0x0820, 0x0820, + 0x0820, 0x0820, 0x0920, 0x0A38, + 0x0820, 0x0820, 0x0820, 0x0820, + 0x0820, 0x0820, 0x0920, 0x0A38, /* 16 */ + 0x0820, 0x0820, 0x0820, 0x0820, + 0x0820, 0x0820, 0x0920, 0x0A38, + 0x0820, 0x0820, 0x0820, 0x0820, + 0x0820, 0x0820, 0x0920, 0x0A38, /* 32 */ + 0x0820, 0x0820, 0x0820, 0x0820, + 0x0820, 0x0820, 0x0920, 0x0A38, + 0x0820, 0x0820, 0x0820, 0x0820, +}; + static inline void assert_sizes(void) { BUILD_BUG_ON(B43_TAB_ROTOR_SIZE != ARRAY_SIZE(b43_tab_rotor)); @@ -317,36 +359,65 @@ static inline void assert_sizes(void) BUILD_BUG_ON(B43_TAB_NOISEA3_SIZE != ARRAY_SIZE(b43_tab_noisea3)); BUILD_BUG_ON(B43_TAB_NOISEG1_SIZE != ARRAY_SIZE(b43_tab_noiseg1)); BUILD_BUG_ON(B43_TAB_NOISEG2_SIZE != ARRAY_SIZE(b43_tab_noiseg2)); - BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != + BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != + ARRAY_SIZE(b43_tab_noisescalea2)); + BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != + ARRAY_SIZE(b43_tab_noisescalea3)); + BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != ARRAY_SIZE(b43_tab_noisescaleg1)); - BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != + BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != ARRAY_SIZE(b43_tab_noisescaleg2)); - BUILD_BUG_ON(B43_TAB_NOISESCALEG_SIZE != + BUILD_BUG_ON(B43_TAB_NOISESCALE_SIZE != ARRAY_SIZE(b43_tab_noisescaleg3)); BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr1)); BUILD_BUG_ON(B43_TAB_SIGMASQR_SIZE != ARRAY_SIZE(b43_tab_sigmasqr2)); + BUILD_BUG_ON(B43_TAB_RSSIAGC1_SIZE != ARRAY_SIZE(b43_tab_rssiagc1)); + BUILD_BUG_ON(B43_TAB_RSSIAGC2_SIZE != ARRAY_SIZE(b43_tab_rssiagc2)); } u16 b43_ofdmtab_read16(struct b43_wldev *dev, u16 table, u16 offset) { - assert_sizes(); + struct b43_phy *phy = &dev->phy; + u16 addr; + + addr = table + offset; + if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) { + b43_phy_write(dev, B43_PHY_OTABLECTL, addr); + phy->ofdm_valid = 1; + } + phy->ofdm_addr = addr; - b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); return b43_phy_read(dev, B43_PHY_OTABLEI); + assert_sizes(); } void b43_ofdmtab_write16(struct b43_wldev *dev, u16 table, u16 offset, u16 value) { - b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); + struct b43_phy *phy = &dev->phy; + u16 addr; + + addr = table + offset; + if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) { + b43_phy_write(dev, B43_PHY_OTABLECTL, addr); + phy->ofdm_valid = 2; + } + phy->ofdm_addr = addr; b43_phy_write(dev, B43_PHY_OTABLEI, value); } u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) { + struct b43_phy *phy = &dev->phy; u32 ret; + u16 addr; - b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); + addr = table + offset; + if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 1) { + b43_phy_write(dev, B43_PHY_OTABLECTL, addr); + phy->ofdm_valid = 1; + } + phy->ofdm_addr = addr; ret = b43_phy_read(dev, B43_PHY_OTABLEQ); ret <<= 16; ret |= b43_phy_read(dev, B43_PHY_OTABLEI); @@ -357,9 +428,17 @@ u32 b43_ofdmtab_read32(struct b43_wldev *dev, u16 table, u16 offset) void b43_ofdmtab_write32(struct b43_wldev *dev, u16 table, u16 offset, u32 value) { - b43_phy_write(dev, B43_PHY_OTABLECTL, table + offset); + struct b43_phy *phy = &dev->phy; + u16 addr; + + addr = table + offset; + if (addr - 1 != phy->ofdm_addr || phy->ofdm_valid != 2) { + b43_phy_write(dev, B43_PHY_OTABLECTL, addr); + phy->ofdm_valid = 2; + } + phy->ofdm_addr = addr; + b43_phy_write(dev, B43_PHY_OTABLEI, value); - b43_phy_write(dev, B43_PHY_OTABLEQ, (value >> 16)); } u16 b43_gtab_read(struct b43_wldev *dev, u16 table, u16 offset) diff --git a/drivers/net/wireless/b43/tables.h b/drivers/net/wireless/b43/tables.h index 64635d7..80e73c7 100644 --- a/drivers/net/wireless/b43/tables.h +++ b/drivers/net/wireless/b43/tables.h @@ -1,9 +1,9 @@ #ifndef B43_TABLES_H_ #define B43_TABLES_H_ -#define B43_TAB_ROTOR_SIZE 53 +#define B43_TAB_ROTOR_SIZE 53 extern const u32 b43_tab_rotor[]; -#define B43_TAB_RETARD_SIZE 53 +#define B43_TAB_RETARD_SIZE 53 extern const u32 b43_tab_retard[]; #define B43_TAB_FINEFREQA_SIZE 256 extern const u16 b43_tab_finefreqa[]; @@ -17,12 +17,18 @@ extern const u16 b43_tab_noisea3[]; extern const u16 b43_tab_noiseg1[]; #define B43_TAB_NOISEG2_SIZE 8 extern const u16 b43_tab_noiseg2[]; -#define B43_TAB_NOISESCALEG_SIZE 27 +#define B43_TAB_NOISESCALE_SIZE 27 +extern const u16 b43_tab_noisescalea2[]; +extern const u16 b43_tab_noisescalea3[]; extern const u16 b43_tab_noisescaleg1[]; extern const u16 b43_tab_noisescaleg2[]; extern const u16 b43_tab_noisescaleg3[]; #define B43_TAB_SIGMASQR_SIZE 53 extern const u16 b43_tab_sigmasqr1[]; extern const u16 b43_tab_sigmasqr2[]; +#define B43_TAB_RSSIAGC1_SIZE 16 +extern const u16 b43_tab_rssiagc1[]; +#define B43_TAB_RSSIAGC2_SIZE 48 +extern const u16 b43_tab_rssiagc2[]; #endif /* B43_TABLES_H_ */ diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c new file mode 100644 index 0000000..0ba7f94 --- /dev/null +++ b/drivers/net/wireless/b43/wa.c @@ -0,0 +1,666 @@ +/* + + Broadcom B43 wireless driver + + PHY workarounds. + + Copyright (c) 2005-2007 Stefano Brivio + Copyright (c) 2005-2007 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 "main.h" +#include "tables.h" +#include "phy.h" +#include "wa.h" + +static void b43_wa_papd(struct b43_wldev *dev) +{ + u16 backup; + + backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); + b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); + b43_dummy_transmission(dev); + b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); +} + +static void b43_wa_auxclipthr(struct b43_wldev *dev) +{ + b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); +} + +static void b43_wa_afcdac(struct b43_wldev *dev) +{ + b43_phy_write(dev, 0x0035, 0x03FF); + b43_phy_write(dev, 0x0036, 0x0400); +} + +static void b43_wa_txdc_offset(struct b43_wldev *dev) +{ + b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); +} + +void b43_wa_initgains(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9); + b43_phy_write(dev, B43_PHY_LPFGAINCTL, + b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F); + if (phy->rev <= 2) + b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF); + b43_radio_write16(dev, 0x0002, 0x1FBF); + + b43_phy_write(dev, 0x0024, 0x4680); + b43_phy_write(dev, 0x0020, 0x0003); + b43_phy_write(dev, 0x001D, 0x0F40); + b43_phy_write(dev, 0x001F, 0x1C00); + if (phy->rev <= 3) + b43_phy_write(dev, 0x002A, + (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400); + else if (phy->rev == 5) { + b43_phy_write(dev, 0x002A, + (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00); + b43_phy_write(dev, 0x00CC, 0x2121); + } + if (phy->rev >= 3) + b43_phy_write(dev, 0x00BA, 0x3ED5); +} + +static void b43_wa_divider(struct b43_wldev *dev) +{ + b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100); + b43_phy_write(dev, 0x008E, 0x58C1); +} + +static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */ +{ + if (dev->phy.rev <= 2) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7); + } else { + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); + } +} + +static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */ +{ + int i; + + for (i = 0; i < 8; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8); + for (i = 8; i < 16; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8); +} + +static void b43_wa_analog(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + if (phy->analog > 2) { + if (phy->type == B43_PHYTYPE_A) + b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808); + else + b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000); + } else { + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044); + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201); + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040); + } +} + +static void b43_wa_dac(struct b43_wldev *dev) +{ + if (dev->phy.analog == 1) + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, + (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008); + else + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, + (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010); +} + +static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */ +{ + int i; + + if (dev->phy.type == B43_PHYTYPE_A) + for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]); + else + for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]); +} + +static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */ +{ + struct b43_phy *phy = &dev->phy; + int i; + + if (phy->type == B43_PHYTYPE_A) { + if (phy->rev == 2) + for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]); + else + for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]); + } else { + if (phy->rev == 1) + for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]); + else + for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]); + } +} + +static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */ +{ + int i; + + for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) + b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]); +} + +static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */ +{ + struct b43_phy *phy = &dev->phy; + int i; + + if (phy->type == B43_PHYTYPE_A) { + if (phy->rev <= 1) + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, 0); + else if (phy->rev == 2) + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescalea2[i]); + else if (phy->rev == 3) + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescalea3[i]); + else + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescaleg3[i]); + } else { + if (phy->rev >= 6) { + if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescaleg3[i]); + else + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescaleg2[i]); + } else { + for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) + b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, + i, b43_tab_noisescaleg1[i]); + } + } +} + +static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */ +{ + int i; + + for (i = 0; i < B43_TAB_RETARD_SIZE; i++) + b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD, + i, b43_tab_retard[i]); +} + +static void b43_wa_txlna_gain(struct b43_wldev *dev) +{ + b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000); +} + +static void b43_wa_crs_reset(struct b43_wldev *dev) +{ + b43_phy_write(dev, 0x002C, 0x0064); +} + +static void b43_wa_2060txlna_gain(struct b43_wldev *dev) +{ + b43_hf_write(dev, b43_hf_read(dev) | + B43_HF_2060W); +} + +static void b43_wa_lms(struct b43_wldev *dev) +{ + b43_phy_write(dev, 0x0055, + (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004); +} + +static void b43_wa_mixedsignal(struct b43_wldev *dev) +{ + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3); +} + +static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */ +{ + struct b43_phy *phy = &dev->phy; + int i; + const u16 *tab; + + if (phy->type == B43_PHYTYPE_A) { + tab = b43_tab_sigmasqr1; + } else if (phy->type == B43_PHYTYPE_G) { + tab = b43_tab_sigmasqr2; + } else { + B43_WARN_ON(1); + return; + } + + for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ, + i, tab[i]); + } +} + +static void b43_wa_iqadc(struct b43_wldev *dev) +{ + if (dev->phy.analog == 4) + b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0, + b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000); +} + +static void b43_wa_crs_ed(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + if (phy->rev == 1) { + b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x4F19); + } else if (phy->rev == 2) { + b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x1861); + b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x1861); + b43_phy_write(dev, B43_PHY_ANTDWELL, + b43_phy_read(dev, B43_PHY_ANTDWELL) + | 0x0800); + } else { + b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x0098); + b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x0070); + b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080); + b43_phy_write(dev, B43_PHY_ANTDWELL, + b43_phy_read(dev, B43_PHY_ANTDWELL) + | 0x0800); + } +} + +static void b43_wa_crs_thr(struct b43_wldev *dev) +{ + b43_phy_write(dev, B43_PHY_CRS0, + (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000); +} + +static void b43_wa_crs_blank(struct b43_wldev *dev) +{ + b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A); +} + +static void b43_wa_cck_shiftbits(struct b43_wldev *dev) +{ + b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026); +} + +static void b43_wa_wrssi_offset(struct b43_wldev *dev) +{ + int i; + + if (dev->phy.rev == 1) { + for (i = 0; i < 16; i++) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1, + i, 0x0020); + } + } else { + for (i = 0; i < 32; i++) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI, + i, 0x0820); + } + } +} + +static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev) +{ + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15); + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20); +} + +static void b43_wa_altagc(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + if (phy->rev == 1) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D); + b43_phy_write(dev, B43_PHY_LMS, 4); + } else { + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); + } + + b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA, + (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700); + b43_phy_write(dev, B43_PHY_OFDM(0x1A), + (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F); + b43_phy_write(dev, B43_PHY_OFDM(0x1A), + (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80); + b43_phy_write(dev, B43_PHY_ANTWRSETT, + (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300); + b43_radio_write16(dev, 0x7A, + b43_radio_read16(dev, 0x7A) | 0x0008); + b43_phy_write(dev, B43_PHY_N1P1GAIN, + (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008); + b43_phy_write(dev, B43_PHY_P1P2GAIN, + (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600); + b43_phy_write(dev, B43_PHY_N1N2GAIN, + (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700); + b43_phy_write(dev, B43_PHY_N1P1GAIN, + (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100); + if (phy->rev == 1) { + b43_phy_write(dev, B43_PHY_N1N2GAIN, + (b43_phy_read(dev, B43_PHY_N1N2GAIN) + & ~0x000F) | 0x0007); + } + b43_phy_write(dev, B43_PHY_OFDM(0x88), + (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C); + b43_phy_write(dev, B43_PHY_OFDM(0x88), + (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200); + b43_phy_write(dev, B43_PHY_OFDM(0x96), + (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C); + b43_phy_write(dev, B43_PHY_OFDM(0x89), + (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020); + b43_phy_write(dev, B43_PHY_OFDM(0x89), + (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200); + b43_phy_write(dev, B43_PHY_OFDM(0x82), + (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E); + b43_phy_write(dev, B43_PHY_OFDM(0x96), + (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00); + b43_phy_write(dev, B43_PHY_OFDM(0x81), + (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028); + b43_phy_write(dev, B43_PHY_OFDM(0x81), + (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00); + if (phy->rev == 1) { + b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002); + } else { + b43_phy_write(dev, B43_PHY_OFDM(0x1B), + b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E); + b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A); + b43_phy_write(dev, B43_PHY_LPFGAINCTL, + (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004); + if (phy->rev >= 6) { + b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); + b43_phy_write(dev, B43_PHY_LPFGAINCTL, + (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000); + } + } + b43_phy_write(dev, B43_PHY_DIVSRCHIDX, + (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x7F7F) | 0x7874); + b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00); + if (phy->rev == 1) { + b43_phy_write(dev, B43_PHY_DIVP1P2GAIN, + (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600); + b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E); + b43_phy_write(dev, B43_PHY_ANTWRSETT, + (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E); + b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28); + } else { + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16); + b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28); + } + if (phy->rev >= 6) { + b43_phy_write(dev, B43_PHY_OFDM(0x26), + b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003); + b43_phy_write(dev, B43_PHY_OFDM(0x26), + b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000); + } +} + +static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */ +{ + b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480); +} + +static void b43_wa_cpll_nonpilot(struct b43_wldev *dev) +{ + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0); + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0); +} + +static void b43_wa_rssi_adc(struct b43_wldev *dev) +{ + if (dev->phy.analog == 4) + b43_phy_write(dev, 0x00DC, 0x7454); +} + +static void b43_wa_boards_a(struct b43_wldev *dev) +{ + struct ssb_bus *bus = dev->dev->bus; + + if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && + bus->boardinfo.type == SSB_BOARD_BU4306 && + bus->boardinfo.rev < 0x30) { + b43_phy_write(dev, 0x0010, 0xE000); + b43_phy_write(dev, 0x0013, 0x0140); + b43_phy_write(dev, 0x0014, 0x0280); + } else { + if (bus->boardinfo.type == SSB_BOARD_MP4318 && + bus->boardinfo.rev < 0x20) { + b43_phy_write(dev, 0x0013, 0x0210); + b43_phy_write(dev, 0x0014, 0x0840); + } else { + b43_phy_write(dev, 0x0013, 0x0140); + b43_phy_write(dev, 0x0014, 0x0280); + } + if (dev->phy.rev <= 4) + b43_phy_write(dev, 0x0010, 0xE000); + else + b43_phy_write(dev, 0x0010, 0x2000); + b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039); + b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040); + } +} + +static void b43_wa_boards_g(struct b43_wldev *dev) +{ + struct ssb_bus *bus = dev->dev->bus; + struct b43_phy *phy = &dev->phy; + + if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || + bus->boardinfo.type != SSB_BOARD_BU4306 || + bus->boardinfo.rev != 0x17) { + if (phy->rev < 2) { + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); + } else { + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); + if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && + (phy->rev >= 7)) { + b43_phy_write(dev, B43_PHY_EXTG(0x11), + b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000); + b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002); + } + } + } + if (bus->sprom.boardflags_lo & B43_BFL_FEM) { + b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); + b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); + } +} + +void b43_wa_all(struct b43_wldev *dev) +{ + struct b43_phy *phy = &dev->phy; + + if (phy->type == B43_PHYTYPE_A) { + switch (phy->rev) { + case 2: + b43_wa_papd(dev); + b43_wa_auxclipthr(dev); + b43_wa_afcdac(dev); + b43_wa_txdc_offset(dev); + b43_wa_initgains(dev); + b43_wa_divider(dev); + b43_wa_gt(dev); + b43_wa_rssi_lt(dev); + b43_wa_analog(dev); + b43_wa_dac(dev); + b43_wa_fft(dev); + b43_wa_nft(dev); + b43_wa_rt(dev); + b43_wa_nst(dev); + b43_wa_art(dev); + b43_wa_txlna_gain(dev); + b43_wa_crs_reset(dev); + b43_wa_2060txlna_gain(dev); + b43_wa_lms(dev); + break; + case 3: + b43_wa_papd(dev); + b43_wa_mixedsignal(dev); + b43_wa_rssi_lt(dev); + b43_wa_txdc_offset(dev); + b43_wa_initgains(dev); + b43_wa_dac(dev); + b43_wa_nft(dev); + b43_wa_nst(dev); + b43_wa_msst(dev); + b43_wa_analog(dev); + b43_wa_gt(dev); + b43_wa_txpuoff_rxpuon(dev); + b43_wa_txlna_gain(dev); + break; + case 5: + b43_wa_iqadc(dev); + case 6: + b43_wa_papd(dev); + b43_wa_rssi_lt(dev); + b43_wa_txdc_offset(dev); + b43_wa_initgains(dev); + b43_wa_dac(dev); + b43_wa_nft(dev); + b43_wa_nst(dev); + b43_wa_msst(dev); + b43_wa_analog(dev); + b43_wa_gt(dev); + b43_wa_txpuoff_rxpuon(dev); + b43_wa_txlna_gain(dev); + break; + case 7: + b43_wa_iqadc(dev); + b43_wa_papd(dev); + b43_wa_rssi_lt(dev); + b43_wa_txdc_offset(dev); + b43_wa_initgains(dev); + b43_wa_dac(dev); + b43_wa_nft(dev); + b43_wa_nst(dev); + b43_wa_msst(dev); + b43_wa_analog(dev); + b43_wa_gt(dev); + b43_wa_txpuoff_rxpuon(dev); + b43_wa_txlna_gain(dev); + b43_wa_rssi_adc(dev); + default: + B43_WARN_ON(1); + } + b43_wa_boards_a(dev); + } else if (phy->type == B43_PHYTYPE_G) { + switch (phy->rev) { + case 1://XXX review rev1 + b43_wa_crs_ed(dev); + b43_wa_crs_thr(dev); + b43_wa_crs_blank(dev); + b43_wa_cck_shiftbits(dev); + b43_wa_fft(dev); + b43_wa_nft(dev); + b43_wa_rt(dev); + b43_wa_nst(dev); + b43_wa_art(dev); + b43_wa_wrssi_offset(dev); + b43_wa_altagc(dev); + break; + case 2: + case 6: + case 7: + case 8: + case 9: + b43_wa_tr_ltov(dev); + b43_wa_crs_ed(dev); + b43_wa_rssi_lt(dev); + b43_wa_nft(dev); + b43_wa_nst(dev); + b43_wa_msst(dev); + b43_wa_wrssi_offset(dev); + b43_wa_altagc(dev); + b43_wa_analog(dev); + b43_wa_txpuoff_rxpuon(dev); + break; + default: + B43_WARN_ON(1); + } + b43_wa_boards_g(dev); + } else { /* No N PHY support so far */ + B43_WARN_ON(1); + } + + b43_wa_cpll_nonpilot(dev); +} diff --git a/drivers/net/wireless/b43/wa.h b/drivers/net/wireless/b43/wa.h new file mode 100644 index 0000000..e163c5e --- /dev/null +++ b/drivers/net/wireless/b43/wa.h @@ -0,0 +1,7 @@ +#ifndef B43_WA_H_ +#define B43_WA_H_ + +void b43_wa_initgains(struct b43_wldev *dev); +void b43_wa_all(struct b43_wldev *dev); + +#endif /* B43_WA_H_ */ diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 0bd6f8a..d946eb6 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -5,7 +5,7 @@ Transmission (TX/RX) related functions. Copyright (C) 2005 Martin Langer - Copyright (C) 2005 Stefano Brivio + Copyright (C) 2005 Stefano Brivio Copyright (C) 2005, 2006 Michael Buesch Copyright (C) 2005 Danny van Dyk Copyright (C) 2005 Andreas Jaggi @@ -294,6 +294,8 @@ static void generate_txhdr_fw4(struct b43_wldev *dev, mac_ctl |= B43_TX4_MAC_STMSDU; if (phy->type == B43_PHYTYPE_A) mac_ctl |= B43_TX4_MAC_5GHZ; + if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT) + mac_ctl |= B43_TX4_MAC_LONGFRAME; /* Generate the RTS or CTS-to-self frame */ if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) || @@ -342,7 +344,6 @@ static void generate_txhdr_fw4(struct b43_wldev *dev, b43_plcp_get_ratecode_cck(rts_rate); if (rts_rate_fb_ofdm) extra_ft |= B43_TX4_EFT_RTSFBOFDM; - mac_ctl |= B43_TX4_MAC_LONGFRAME; } /* Magic cookie */ @@ -384,7 +385,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, else tmp -= 3; } else { - if (dev->dev->bus->sprom.r1. + if (dev->dev->bus->sprom. boardflags_lo & B43_BFL_RSSI) { if (in_rssi > 63) in_rssi = 63; @@ -488,7 +489,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) } wlhdr = (struct ieee80211_hdr *)(skb->data); fctl = le16_to_cpu(wlhdr->frame_control); - skb_trim(skb, skb->len - FCS_LEN); if (macstat & B43_RX_MAC_DEC) { unsigned int keyidx; @@ -525,7 +525,23 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) else status.rate = b43_plcp_get_bitrate_cck(plcp); status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); - status.mactime = mactime; + + /* + * If monitors are present get full 64-bit timestamp. This + * code assumes we get to process the packet within 16 bits + * of timestamp, i.e. about 65 milliseconds after the PHY + * received the first symbol. + */ + if (dev->wl->radiotap_enabled) { + u16 low_mactime_now; + + b43_tsf_read(dev, &status.mactime); + low_mactime_now = status.mactime; + status.mactime = status.mactime & ~0xFFFFULL; + status.mactime += mactime; + if (low_mactime_now <= mactime) + status.mactime -= 0x10000; + } chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; switch (chanstat & B43_RX_CHAN_PHYTYPE) { diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index 7e23ec2..6745579 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig @@ -34,6 +34,22 @@ config B43LEGACY_PCICORE_AUTOSELECT select SSB_DRIVER_PCICORE default y +# LED support +# This config option automatically enables b43legacy LEDS support, +# if it's possible. +config B43LEGACY_LEDS + bool + depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) + default y + +# RFKILL support +# This config option automatically enables b43legacy RFKILL support, +# if it's possible. +config B43LEGACY_RFKILL + bool + depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) + default y + config B43LEGACY_DEBUG bool "Broadcom 43xx-legacy debugging" depends on B43LEGACY diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile index ec3a248..80cdb73 100644 --- a/drivers/net/wireless/b43legacy/Makefile +++ b/drivers/net/wireless/b43legacy/Makefile @@ -1,14 +1,19 @@ -obj-$(CONFIG_B43LEGACY) += b43legacy.o -b43legacy-obj-$(CONFIG_B43LEGACY_DEBUG) += debugfs.o +# b43legacy core +b43legacy-y += main.o +b43legacy-y += ilt.o +b43legacy-y += phy.o +b43legacy-y += radio.o +b43legacy-y += sysfs.o +b43legacy-y += xmit.o +# b43 RFKILL button support +b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o +# b43legacy LED support +b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o +# b43legacy debugging +b43legacy-$(CONFIG_B43LEGACY_DEBUG) += debugfs.o +# b43legacy DMA and PIO +b43legacy-$(CONFIG_B43LEGACY_DMA) += dma.o +b43legacy-$(CONFIG_B43LEGACY_PIO) += pio.o -b43legacy-obj-$(CONFIG_B43LEGACY_DMA) += dma.o -b43legacy-obj-$(CONFIG_B43LEGACY_PIO) += pio.o +obj-$(CONFIG_B43LEGACY) += b43legacy.o -b43legacy-objs := main.o \ - ilt.o \ - leds.o \ - phy.o \ - radio.o \ - sysfs.o \ - xmit.o \ - $(b43legacy-obj-y) diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index afe145c..e4de437 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -19,6 +19,7 @@ #include "debugfs.h" #include "leds.h" +#include "rfkill.h" #include "phy.h" @@ -275,6 +276,8 @@ #define B43legacy_DEFAULT_SHORT_RETRY_LIMIT 7 #define B43legacy_DEFAULT_LONG_RETRY_LIMIT 4 +#define B43legacy_PHY_TX_BADNESS_LIMIT 1000 + /* Max size of a security key */ #define B43legacy_SEC_KEYSIZE 16 /* Security algorithms. */ @@ -510,6 +513,9 @@ struct b43legacy_phy { u16 lofcal; u16 initval; + + /* PHY TX errors counter. */ + atomic_t txerr_cnt; }; /* Data structures for DMA transmission, per 80211 core. */ @@ -592,9 +598,14 @@ struct b43legacy_wl { u8 rng_initialized; char rng_name[30 + 1]; + /* The RF-kill button */ + struct b43legacy_rfkill rfkill; + /* List of all wireless devices on this chip */ struct list_head devlist; u8 nr_devs; + + bool radiotap_enabled; }; /* Pointers to the firmware data and meta information about it. */ @@ -663,8 +674,11 @@ struct b43legacy_wldev { /* Various statistics about the physical device. */ struct b43legacy_stats stats; -#define B43legacy_NR_LEDS 4 - struct b43legacy_led leds[B43legacy_NR_LEDS]; + /* The device LEDs. */ + struct b43legacy_led led_tx; + struct b43legacy_led led_rx; + struct b43legacy_led led_assoc; + struct b43legacy_led led_radio; /* Reason code of the last interrupt. */ u32 irq_reason; diff --git a/drivers/net/wireless/b43legacy/debugfs.c b/drivers/net/wireless/b43legacy/debugfs.c index 619b453..03ce082 100644 --- a/drivers/net/wireless/b43legacy/debugfs.c +++ b/drivers/net/wireless/b43legacy/debugfs.c @@ -209,7 +209,7 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf, struct b43legacy_wldev *dev; struct b43legacy_debugfs_fops *dfops; struct b43legacy_dfs_file *dfile; - ssize_t ret = 0; + ssize_t uninitialized_var(ret); char *buf; const size_t bufsize = 1024 * 128; const size_t buforder = get_order(bufsize); diff --git a/drivers/net/wireless/b43legacy/ilt.c b/drivers/net/wireless/b43legacy/ilt.c index 247fc78..a849078 100644 --- a/drivers/net/wireless/b43legacy/ilt.c +++ b/drivers/net/wireless/b43legacy/ilt.c @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index a584ea8..f0affb7 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c @@ -1,13 +1,13 @@ /* - Broadcom B43legacy wireless driver + Broadcom B43 wireless driver + LED control Copyright (c) 2005 Martin Langer , - Stefano Brivio - Michael Buesch - Danny van Dyk - Andreas Jaggi - Copyright (c) 2007 Larry Finger + Copyright (c) 2005 Stefano Brivio + Copyright (c) 2005-2007 Michael Buesch + Copyright (c) 2005 Danny van Dyk + Copyright (c) 2005 Andreas Jaggi 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 @@ -26,273 +26,212 @@ */ -#include "leds.h" #include "b43legacy.h" -#include "main.h" - -static void b43legacy_led_changestate(struct b43legacy_led *led) -{ - struct b43legacy_wldev *dev = led->dev; - const int index = led->index; - u16 ledctl; +#include "leds.h" - B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS)); - B43legacy_WARN_ON(!led->blink_interval); - ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); - ledctl ^= (1 << index); - b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); -} -static void b43legacy_led_blink(unsigned long d) +static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, + bool activelow) { - struct b43legacy_led *led = (struct b43legacy_led *)d; - struct b43legacy_wldev *dev = led->dev; + struct b43legacy_wl *wl = dev->wl; unsigned long flags; + u16 ctl; - spin_lock_irqsave(&dev->wl->leds_lock, flags); - if (led->blink_interval) { - b43legacy_led_changestate(led); - mod_timer(&led->blink_timer, jiffies + led->blink_interval); - } - spin_unlock_irqrestore(&dev->wl->leds_lock, flags); + spin_lock_irqsave(&wl->leds_lock, flags); + ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); + if (activelow) + ctl &= ~(1 << led_index); + else + ctl |= (1 << led_index); + b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl); + spin_unlock_irqrestore(&wl->leds_lock, flags); } -static void b43legacy_led_blink_start(struct b43legacy_led *led, - unsigned long interval) +static void b43legacy_led_turn_off(struct b43legacy_wldev *dev, u8 led_index, + bool activelow) { - if (led->blink_interval) - return; - led->blink_interval = interval; - b43legacy_led_changestate(led); - led->blink_timer.expires = jiffies + interval; - add_timer(&led->blink_timer); + struct b43legacy_wl *wl = dev->wl; + unsigned long flags; + u16 ctl; + + spin_lock_irqsave(&wl->leds_lock, flags); + ctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); + if (activelow) + ctl |= (1 << led_index); + else + ctl &= ~(1 << led_index); + b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ctl); + spin_unlock_irqrestore(&wl->leds_lock, flags); } -static void b43legacy_led_blink_stop(struct b43legacy_led *led, int sync) +/* Callback from the LED subsystem. */ +static void b43legacy_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) { + struct b43legacy_led *led = container_of(led_dev, struct b43legacy_led, + led_dev); struct b43legacy_wldev *dev = led->dev; - const int index = led->index; - u16 ledctl; + bool radio_enabled; - if (!led->blink_interval) - return; - if (unlikely(sync)) - del_timer_sync(&led->blink_timer); - else - del_timer(&led->blink_timer); - led->blink_interval = 0; + /* Checking the radio-enabled status here is slightly racy, + * but we want to avoid the locking overhead and we don't care + * whether the LED has the wrong state for a second. */ + radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable); - /* Make sure the LED is turned off. */ - B43legacy_WARN_ON(!(index >= 0 && index < B43legacy_NR_LEDS)); - ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); - if (led->activelow) - ledctl |= (1 << index); + if (brightness == LED_OFF || !radio_enabled) + b43legacy_led_turn_off(dev, led->index, led->activelow); else - ledctl &= ~(1 << index); - b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); + b43legacy_led_turn_on(dev, led->index, led->activelow); } -static void b43legacy_led_init_hardcoded(struct b43legacy_wldev *dev, - struct b43legacy_led *led, - int led_index) +static int b43legacy_register_led(struct b43legacy_wldev *dev, + struct b43legacy_led *led, + const char *name, char *default_trigger, + u8 led_index, bool activelow) { - struct ssb_bus *bus = dev->dev->bus; + int err; + + b43legacy_led_turn_off(dev, led_index, activelow); + if (led->dev) + return -EEXIST; + if (!default_trigger) + return -EINVAL; + led->dev = dev; + led->index = led_index; + led->activelow = activelow; + strncpy(led->name, name, sizeof(led->name)); + + led->led_dev.name = led->name; + led->led_dev.default_trigger = default_trigger; + led->led_dev.brightness_set = b43legacy_led_brightness_set; + + err = led_classdev_register(dev->dev->dev, &led->led_dev); + if (err) { + b43legacywarn(dev->wl, "LEDs: Failed to register %s\n", name); + led->dev = NULL; + return err; + } + return 0; +} - /* This function is called, if the behaviour (and activelow) - * information for a LED is missing in the SPROM. - * We hardcode the behaviour values for various devices here. - * Note that the B43legacy_LED_TEST_XXX behaviour values can - * be used to figure out which led is mapped to which index. - */ +static void b43legacy_unregister_led(struct b43legacy_led *led) +{ + if (!led->dev) + return; + led_classdev_unregister(&led->led_dev); + b43legacy_led_turn_off(led->dev, led->index, led->activelow); + led->dev = NULL; +} + +static void b43legacy_map_led(struct b43legacy_wldev *dev, + u8 led_index, + enum b43legacy_led_behaviour behaviour, + bool activelow) +{ + struct ieee80211_hw *hw = dev->wl->hw; + char name[B43legacy_LED_MAX_NAME_LEN + 1]; - switch (led_index) { - case 0: - led->behaviour = B43legacy_LED_ACTIVITY; - led->activelow = 1; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) - led->behaviour = B43legacy_LED_RADIO_ALL; + /* Map the b43 specific LED behaviour value to the + * generic LED triggers. */ + switch (behaviour) { + case B43legacy_LED_INACTIVE: break; - case 1: - led->behaviour = B43legacy_LED_RADIO_B; - if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) - led->behaviour = B43legacy_LED_ASSOC; + case B43legacy_LED_OFF: + b43legacy_led_turn_off(dev, led_index, activelow); break; - case 2: - led->behaviour = B43legacy_LED_RADIO_A; + case B43legacy_LED_ON: + b43legacy_led_turn_on(dev, led_index, activelow); break; - case 3: - led->behaviour = B43legacy_LED_OFF; + case B43legacy_LED_ACTIVITY: + case B43legacy_LED_TRANSFER: + case B43legacy_LED_APTRANSFER: + snprintf(name, sizeof(name), + "b43legacy-%s:tx", wiphy_name(hw->wiphy)); + b43legacy_register_led(dev, &dev->led_tx, name, + ieee80211_get_tx_led_name(hw), + led_index, activelow); + snprintf(name, sizeof(name), + "b43legacy-%s:rx", wiphy_name(hw->wiphy)); + b43legacy_register_led(dev, &dev->led_rx, name, + ieee80211_get_rx_led_name(hw), + led_index, activelow); + break; + case B43legacy_LED_RADIO_ALL: + case B43legacy_LED_RADIO_A: + case B43legacy_LED_RADIO_B: + case B43legacy_LED_MODE_BG: + snprintf(name, sizeof(name), + "b43legacy-%s:radio", wiphy_name(hw->wiphy)); + b43legacy_register_led(dev, &dev->led_radio, name, + b43legacy_rfkill_led_name(dev), + led_index, activelow); + break; + case B43legacy_LED_WEIRD: + case B43legacy_LED_ASSOC: + snprintf(name, sizeof(name), + "b43legacy-%s:assoc", wiphy_name(hw->wiphy)); + b43legacy_register_led(dev, &dev->led_assoc, name, + ieee80211_get_assoc_led_name(hw), + led_index, activelow); break; default: - B43legacy_BUG_ON(1); + b43legacywarn(dev->wl, "LEDs: Unknown behaviour 0x%02X\n", + behaviour); + break; } } -int b43legacy_leds_init(struct b43legacy_wldev *dev) +void b43legacy_leds_init(struct b43legacy_wldev *dev) { - struct b43legacy_led *led; + struct ssb_bus *bus = dev->dev->bus; u8 sprom[4]; int i; - - sprom[0] = dev->dev->bus->sprom.r1.gpio0; - sprom[1] = dev->dev->bus->sprom.r1.gpio1; - sprom[2] = dev->dev->bus->sprom.r1.gpio2; - sprom[3] = dev->dev->bus->sprom.r1.gpio3; - - for (i = 0; i < B43legacy_NR_LEDS; i++) { - led = &(dev->leds[i]); - led->index = i; - led->dev = dev; - setup_timer(&led->blink_timer, - b43legacy_led_blink, - (unsigned long)led); - - if (sprom[i] == 0xFF) - b43legacy_led_init_hardcoded(dev, led, i); - else { - led->behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR; - led->activelow = !!(sprom[i] & - B43legacy_LED_ACTIVELOW); + enum b43legacy_led_behaviour behaviour; + bool activelow; + + sprom[0] = bus->sprom.gpio0; + sprom[1] = bus->sprom.gpio1; + sprom[2] = bus->sprom.gpio2; + sprom[3] = bus->sprom.gpio3; + + for (i = 0; i < 4; i++) { + if (sprom[i] == 0xFF) { + /* There is no LED information in the SPROM + * for this LED. Hardcode it here. */ + activelow = 0; + switch (i) { + case 0: + behaviour = B43legacy_LED_ACTIVITY; + activelow = 1; + if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) + behaviour = B43legacy_LED_RADIO_ALL; + break; + case 1: + behaviour = B43legacy_LED_RADIO_B; + if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) + behaviour = B43legacy_LED_ASSOC; + break; + case 2: + behaviour = B43legacy_LED_RADIO_A; + break; + case 3: + behaviour = B43legacy_LED_OFF; + break; + default: + B43legacy_WARN_ON(1); + return; + } + } else { + behaviour = sprom[i] & B43legacy_LED_BEHAVIOUR; + activelow = !!(sprom[i] & B43legacy_LED_ACTIVELOW); } + b43legacy_map_led(dev, i, behaviour, activelow); } - - return 0; } void b43legacy_leds_exit(struct b43legacy_wldev *dev) { - struct b43legacy_led *led; - int i; - - for (i = 0; i < B43legacy_NR_LEDS; i++) { - led = &(dev->leds[i]); - b43legacy_led_blink_stop(led, 1); - } - b43legacy_leds_switch_all(dev, 0); -} - -void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity) -{ - struct b43legacy_led *led; - struct b43legacy_phy *phy = &dev->phy; - const int transferring = (jiffies - dev->stats.last_tx) - < B43legacy_LED_XFER_THRES; - int i; - int turn_on; - unsigned long interval = 0; - u16 ledctl; - unsigned long flags; - bool radio_enabled = (phy->radio_on && dev->radio_hw_enable); - - spin_lock_irqsave(&dev->wl->leds_lock, flags); - ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); - for (i = 0; i < B43legacy_NR_LEDS; i++) { - led = &(dev->leds[i]); - - turn_on = 0; - switch (led->behaviour) { - case B43legacy_LED_INACTIVE: - continue; - case B43legacy_LED_OFF: - break; - case B43legacy_LED_ON: - turn_on = 1; - break; - case B43legacy_LED_ACTIVITY: - turn_on = activity; - break; - case B43legacy_LED_RADIO_ALL: - turn_on = radio_enabled; - break; - case B43legacy_LED_RADIO_A: - break; - case B43legacy_LED_RADIO_B: - turn_on = radio_enabled; - break; - case B43legacy_LED_MODE_BG: - if (phy->type == B43legacy_PHYTYPE_G && radio_enabled) - turn_on = 1; - break; - case B43legacy_LED_TRANSFER: - if (transferring) - b43legacy_led_blink_start(led, - B43legacy_LEDBLINK_MEDIUM); - else - b43legacy_led_blink_stop(led, 0); - continue; - case B43legacy_LED_APTRANSFER: - if (b43legacy_is_mode(dev->wl, - IEEE80211_IF_TYPE_AP)) { - if (transferring) { - interval = B43legacy_LEDBLINK_FAST; - turn_on = 1; - } - } else { - turn_on = 1; - if (transferring) - interval = B43legacy_LEDBLINK_FAST; - else - turn_on = 0; - } - if (turn_on) - b43legacy_led_blink_start(led, interval); - else - b43legacy_led_blink_stop(led, 0); - continue; - case B43legacy_LED_WEIRD: - break; - case B43legacy_LED_ASSOC: - turn_on = 1; -#ifdef CONFIG_B43LEGACY_DEBUG - case B43legacy_LED_TEST_BLINKSLOW: - b43legacy_led_blink_start(led, B43legacy_LEDBLINK_SLOW); - continue; - case B43legacy_LED_TEST_BLINKMEDIUM: - b43legacy_led_blink_start(led, - B43legacy_LEDBLINK_MEDIUM); - continue; - case B43legacy_LED_TEST_BLINKFAST: - b43legacy_led_blink_start(led, B43legacy_LEDBLINK_FAST); - continue; -#endif /* CONFIG_B43LEGACY_DEBUG */ - default: - B43legacy_BUG_ON(1); - }; - - if (led->activelow) - turn_on = !turn_on; - if (turn_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); - spin_unlock_irqrestore(&dev->wl->leds_lock, flags); -} - -void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on) -{ - struct b43legacy_led *led; - u16 ledctl; - int i; - int bit_on; - unsigned long flags; - - spin_lock_irqsave(&dev->wl->leds_lock, flags); - ledctl = b43legacy_read16(dev, B43legacy_MMIO_GPIO_CONTROL); - for (i = 0; i < B43legacy_NR_LEDS; i++) { - led = &(dev->leds[i]); - if (led->behaviour == B43legacy_LED_INACTIVE) - continue; - if (on) - bit_on = led->activelow ? 0 : 1; - else - bit_on = led->activelow ? 1 : 0; - if (bit_on) - ledctl |= (1 << i); - else - ledctl &= ~(1 << i); - } - b43legacy_write16(dev, B43legacy_MMIO_GPIO_CONTROL, ledctl); - spin_unlock_irqrestore(&dev->wl->leds_lock, flags); + b43legacy_unregister_led(&dev->led_tx); + b43legacy_unregister_led(&dev->led_rx); + b43legacy_unregister_led(&dev->led_assoc); } diff --git a/drivers/net/wireless/b43legacy/leds.h b/drivers/net/wireless/b43legacy/leds.h index b989f50..82167a9 100644 --- a/drivers/net/wireless/b43legacy/leds.h +++ b/drivers/net/wireless/b43legacy/leds.h @@ -1,30 +1,33 @@ #ifndef B43legacy_LEDS_H_ #define B43legacy_LEDS_H_ +struct b43legacy_wldev; + +#ifdef CONFIG_B43LEGACY_LEDS + #include -#include +#include +#define B43legacy_LED_MAX_NAME_LEN 31 + struct b43legacy_led { - u8 behaviour; - bool activelow; - /* Index in the "leds" array in b43legacy_wldev */ - u8 index; struct b43legacy_wldev *dev; - struct timer_list blink_timer; - unsigned long blink_interval; + /* The LED class device */ + struct led_classdev led_dev; + /* The index number of the LED. */ + u8 index; + /* If activelow is true, the LED is ON if the + * bit is switched off. */ + bool activelow; + /* The unique name string for this LED device. */ + char name[B43legacy_LED_MAX_NAME_LEN + 1]; }; -/* Delay between state changes when blinking in jiffies */ -#define B43legacy_LEDBLINK_SLOW (HZ / 1) -#define B43legacy_LEDBLINK_MEDIUM (HZ / 4) -#define B43legacy_LEDBLINK_FAST (HZ / 8) - -#define B43legacy_LED_XFER_THRES (HZ / 100) - #define B43legacy_LED_BEHAVIOUR 0x7F #define B43legacy_LED_ACTIVELOW 0x80 -enum { /* LED behaviour values */ +/* LED behaviour values */ +enum b43legacy_led_behaviour { B43legacy_LED_OFF, B43legacy_LED_ON, B43legacy_LED_ACTIVITY, @@ -37,20 +40,24 @@ enum { /* LED behaviour values */ B43legacy_LED_WEIRD, B43legacy_LED_ASSOC, B43legacy_LED_INACTIVE, - - /* Behaviour values for testing. - * With these values it is easier to figure out - * the real behaviour of leds, in case the SPROM - * is missing information. - */ - B43legacy_LED_TEST_BLINKSLOW, - B43legacy_LED_TEST_BLINKMEDIUM, - B43legacy_LED_TEST_BLINKFAST, }; -int b43legacy_leds_init(struct b43legacy_wldev *dev); +void b43legacy_leds_init(struct b43legacy_wldev *dev); void b43legacy_leds_exit(struct b43legacy_wldev *dev); -void b43legacy_leds_update(struct b43legacy_wldev *dev, int activity); -void b43legacy_leds_switch_all(struct b43legacy_wldev *dev, int on); + +#else /* CONFIG_B43EGACY_LEDS */ +/* LED support disabled */ + +struct b43legacy_led { + /* empty */ +}; + +static inline void b43legacy_leds_init(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_leds_exit(struct b43legacy_wldev *dev) +{ +} +#endif /* CONFIG_B43LEGACY_LEDS */ #endif /* B43legacy_LEDS_H_ */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 32d5e17..aa723ef 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -3,7 +3,7 @@ * Broadcom B43legacy wireless driver * * Copyright (c) 2005 Martin Langer - * Copyright (c) 2005 Stefano Brivio + * Copyright (c) 2005-2007 Stefano Brivio * Copyright (c) 2005, 2006 Michael Buesch * Copyright (c) 2005 Danny van Dyk * Copyright (c) 2005 Andreas Jaggi @@ -75,18 +75,6 @@ module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); MODULE_PARM_DESC(bad_frames_preempt, "enable(1) / disable(0) Bad Frames" " Preemption"); -static int modparam_short_retry = B43legacy_DEFAULT_SHORT_RETRY_LIMIT; -module_param_named(short_retry, modparam_short_retry, int, 0444); -MODULE_PARM_DESC(short_retry, "Short-Retry-Limit (0 - 15)"); - -static int modparam_long_retry = B43legacy_DEFAULT_LONG_RETRY_LIMIT; -module_param_named(long_retry, modparam_long_retry, int, 0444); -MODULE_PARM_DESC(long_retry, "Long-Retry-Limit (0 - 15)"); - -static int modparam_noleds; -module_param_named(noleds, modparam_noleds, int, 0444); -MODULE_PARM_DESC(noleds, "Turn off all LED activity"); - static char modparam_fwpostfix[16]; module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444); MODULE_PARM_DESC(fwpostfix, "Postfix for the firmware files to load."); @@ -1217,7 +1205,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; u32 merged_dma_reason = 0; int i; - int activity = 0; unsigned long flags; spin_lock_irqsave(&dev->wl->irq_lock, flags); @@ -1234,8 +1221,15 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) if (unlikely(reason & B43legacy_IRQ_MAC_TXERR)) b43legacyerr(dev->wl, "MAC transmission error\n"); - if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) + if (unlikely(reason & B43legacy_IRQ_PHY_TXERR)) { b43legacyerr(dev->wl, "PHY transmission error\n"); + rmb(); + if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) { + b43legacyerr(dev->wl, "Too many PHY TX errors, " + "restarting the controller\n"); + b43legacy_controller_restart(dev, "PHY TX errors"); + } + } if (unlikely(merged_dma_reason & (B43legacy_DMAIRQ_FATALMASK | B43legacy_DMAIRQ_NONFATALMASK))) { @@ -1281,7 +1275,6 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) b43legacy_pio_rx(dev->pio.queue0); else b43legacy_dma_rx(dev->dma.rx_ring0); - /* We intentionally don't set "activity" to 1, here. */ } B43legacy_WARN_ON(dma_reason[1] & B43legacy_DMAIRQ_RX_DONE); B43legacy_WARN_ON(dma_reason[2] & B43legacy_DMAIRQ_RX_DONE); @@ -1290,20 +1283,13 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev) b43legacy_pio_rx(dev->pio.queue3); else b43legacy_dma_rx(dev->dma.rx_ring3); - activity = 1; } B43legacy_WARN_ON(dma_reason[4] & B43legacy_DMAIRQ_RX_DONE); B43legacy_WARN_ON(dma_reason[5] & B43legacy_DMAIRQ_RX_DONE); - if (reason & B43legacy_IRQ_TX_OK) { + if (reason & B43legacy_IRQ_TX_OK) handle_irq_transmit_status(dev); - activity = 1; - /* TODO: In AP mode, this also causes sending of powersave - responses. */ - } - if (!modparam_noleds) - b43legacy_leds_update(dev, activity); b43legacy_interrupt_enable(dev, dev->irq_savedstate); mmiowb(); spin_unlock_irqrestore(&dev->wl->irq_lock, flags); @@ -1755,7 +1741,6 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev) B43legacy_MMIO_STATUS_BITFIELD) & 0xFFFF3FFF); - b43legacy_leds_switch_all(dev, 0); b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, b43legacy_read16(dev, B43legacy_MMIO_GPIO_MASK) @@ -1767,7 +1752,7 @@ static int b43legacy_gpio_init(struct b43legacy_wldev *dev) mask |= 0x0060; set |= 0x0060; } - if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_PACTRL) { + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) { b43legacy_write16(dev, B43legacy_MMIO_GPIO_MASK, b43legacy_read16(dev, B43legacy_MMIO_GPIO_MASK) @@ -1811,6 +1796,7 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev) { dev->mac_suspended--; B43legacy_WARN_ON(dev->mac_suspended < 0); + B43legacy_WARN_ON(irqs_disabled()); if (dev->mac_suspended == 0) { b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, b43legacy_read32(dev, @@ -1822,6 +1808,11 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev) b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD); b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); b43legacy_power_saving_ctl_bits(dev, -1, -1); + + /* Re-enable IRQs. */ + spin_lock_irq(&dev->wl->irq_lock); + b43legacy_interrupt_enable(dev, dev->irq_savedstate); + spin_unlock_irq(&dev->wl->irq_lock); } } @@ -1831,20 +1822,31 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev) int i; u32 tmp; + might_sleep(); + B43legacy_WARN_ON(irqs_disabled()); B43legacy_WARN_ON(dev->mac_suspended < 0); + if (dev->mac_suspended == 0) { + /* Mask IRQs before suspending MAC. Otherwise + * the MAC stays busy and won't suspend. */ + spin_lock_irq(&dev->wl->irq_lock); + tmp = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL); + spin_unlock_irq(&dev->wl->irq_lock); + b43legacy_synchronize_irq(dev); + dev->irq_savedstate = tmp; + b43legacy_power_saving_ctl_bits(dev, -1, 1); b43legacy_write32(dev, B43legacy_MMIO_STATUS_BITFIELD, b43legacy_read32(dev, B43legacy_MMIO_STATUS_BITFIELD) & ~B43legacy_SBF_MAC_ENABLED); b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); - for (i = 10000; i; i--) { + for (i = 40; i; i--) { tmp = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON); if (tmp & B43legacy_IRQ_MAC_SUSPENDED) goto out; - udelay(1); + msleep(1); } b43legacyerr(dev->wl, "MAC suspend failed\n"); } @@ -1989,27 +1991,11 @@ static void b43legacy_mgmtframe_txantenna(struct b43legacy_wldev *dev, B43legacy_SHM_SH_PRPHYCTL, tmp); } -/* Returns TRUE, if the radio is enabled in hardware. */ -static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) -{ - if (dev->phy.rev >= 3) { - if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) - & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) - return 1; - } else { - if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) - & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) - return 1; - } - return 0; -} - /* This is the opposite of b43legacy_chip_init() */ static void b43legacy_chip_exit(struct b43legacy_wldev *dev) { - b43legacy_radio_turn_off(dev); - if (!modparam_noleds) - b43legacy_leds_exit(dev); + b43legacy_radio_turn_off(dev, 1); + b43legacy_leds_exit(dev); b43legacy_gpio_cleanup(dev); /* firmware is released later */ } @@ -2039,9 +2025,11 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) err = b43legacy_gpio_init(dev); if (err) goto out; /* firmware is released later */ + b43legacy_leds_init(dev); + err = b43legacy_upload_initvals(dev); if (err) - goto err_gpio_cleanup; + goto err_leds_exit; b43legacy_radio_turn_on(dev); b43legacy_write16(dev, 0x03E6, 0x0000); @@ -2113,14 +2101,18 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev) b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY, dev->dev->bus->chipco.fast_pwrup_delay); + /* PHY TX errors counter. */ + atomic_set(&phy->txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT); + B43legacy_WARN_ON(err != 0); b43legacydbg(dev->wl, "Chip initialized\n"); out: return err; err_radio_off: - b43legacy_radio_turn_off(dev); -err_gpio_cleanup: + b43legacy_radio_turn_off(dev, 1); +err_leds_exit: + b43legacy_leds_exit(dev); b43legacy_gpio_cleanup(dev); goto out; } @@ -2140,7 +2132,7 @@ static void b43legacy_periodic_every120sec(struct b43legacy_wldev *dev) static void b43legacy_periodic_every60sec(struct b43legacy_wldev *dev) { b43legacy_phy_lo_mark_all_unused(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI) { + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) { b43legacy_mac_suspend(dev); b43legacy_calc_nrssi_slope(dev); b43legacy_mac_enable(dev); @@ -2156,20 +2148,9 @@ static void b43legacy_periodic_every30sec(struct b43legacy_wldev *dev) static void b43legacy_periodic_every15sec(struct b43legacy_wldev *dev) { b43legacy_phy_xmitpower(dev); /* FIXME: unless scanning? */ -} -static void b43legacy_periodic_every1sec(struct b43legacy_wldev *dev) -{ - bool radio_hw_enable; - - /* check if radio hardware enabled status changed */ - radio_hw_enable = b43legacy_is_hw_radio_enabled(dev); - if (unlikely(dev->radio_hw_enable != radio_hw_enable)) { - dev->radio_hw_enable = radio_hw_enable; - b43legacyinfo(dev->wl, "Radio hardware status changed to %s\n", - (radio_hw_enable) ? "enabled" : "disabled"); - b43legacy_leds_update(dev, 0); - } + atomic_set(&dev->phy.txerr_cnt, B43legacy_PHY_TX_BADNESS_LIMIT); + wmb(); } static void do_periodic_work(struct b43legacy_wldev *dev) @@ -2177,94 +2158,45 @@ static void do_periodic_work(struct b43legacy_wldev *dev) unsigned int state; state = dev->periodic_state; - if (state % 120 == 0) + if (state % 8 == 0) b43legacy_periodic_every120sec(dev); - if (state % 60 == 0) + if (state % 4 == 0) b43legacy_periodic_every60sec(dev); - if (state % 30 == 0) + if (state % 2 == 0) b43legacy_periodic_every30sec(dev); - if (state % 15 == 0) - b43legacy_periodic_every15sec(dev); - b43legacy_periodic_every1sec(dev); + b43legacy_periodic_every15sec(dev); } -/* Estimate a "Badness" value based on the periodic work - * state-machine state. "Badness" is worse (bigger), if the - * periodic work will take longer. +/* Periodic work locking policy: + * The whole periodic work handler is protected by + * wl->mutex. If another lock is needed somewhere in the + * pwork callchain, it's aquired in-place, where it's needed. */ -static int estimate_periodic_work_badness(unsigned int state) -{ - int badness = 0; - - if (state % 120 == 0) /* every 120 sec */ - badness += 10; - if (state % 60 == 0) /* every 60 sec */ - badness += 5; - if (state % 30 == 0) /* every 30 sec */ - badness += 1; - if (state % 15 == 0) /* every 15 sec */ - badness += 1; - -#define BADNESS_LIMIT 4 - return badness; -} - static void b43legacy_periodic_work_handler(struct work_struct *work) { - struct b43legacy_wldev *dev = - container_of(work, struct b43legacy_wldev, - periodic_work.work); - unsigned long flags; + struct b43legacy_wldev *dev = container_of(work, struct b43legacy_wldev, + periodic_work.work); + struct b43legacy_wl *wl = dev->wl; unsigned long delay; - u32 savedirqs = 0; - int badness; - mutex_lock(&dev->wl->mutex); + mutex_lock(&wl->mutex); if (unlikely(b43legacy_status(dev) != B43legacy_STAT_STARTED)) goto out; if (b43legacy_debug(dev, B43legacy_DBG_PWORK_STOP)) goto out_requeue; - badness = estimate_periodic_work_badness(dev->periodic_state); - if (badness > BADNESS_LIMIT) { - spin_lock_irqsave(&dev->wl->irq_lock, flags); - /* Suspend TX as we don't want to transmit packets while - * we recalibrate the hardware. */ - b43legacy_tx_suspend(dev); - savedirqs = b43legacy_interrupt_disable(dev, - B43legacy_IRQ_ALL); - /* Periodic work will take a long time, so we want it to - * be preemtible and release the spinlock. */ - spin_unlock_irqrestore(&dev->wl->irq_lock, flags); - b43legacy_synchronize_irq(dev); - - do_periodic_work(dev); + do_periodic_work(dev); - spin_lock_irqsave(&dev->wl->irq_lock, flags); - b43legacy_interrupt_enable(dev, savedirqs); - b43legacy_tx_resume(dev); - mmiowb(); - spin_unlock_irqrestore(&dev->wl->irq_lock, flags); - } else { - /* Take the global driver lock. This will lock any operation. */ - spin_lock_irqsave(&dev->wl->irq_lock, flags); - - do_periodic_work(dev); - - mmiowb(); - spin_unlock_irqrestore(&dev->wl->irq_lock, flags); - } dev->periodic_state++; out_requeue: if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST)) delay = msecs_to_jiffies(50); else - delay = round_jiffies_relative(HZ); - queue_delayed_work(dev->wl->hw->workqueue, - &dev->periodic_work, delay); + delay = round_jiffies_relative(HZ * 15); + queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); out: - mutex_unlock(&dev->wl->mutex); + mutex_unlock(&wl->mutex); } static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev) @@ -2366,9 +2298,9 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl) return err; } -static int b43legacy_tx(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ieee80211_tx_control *ctl) +static int b43legacy_op_tx(struct ieee80211_hw *hw, + struct sk_buff *skb, + struct ieee80211_tx_control *ctl) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -2392,15 +2324,15 @@ out: return NETDEV_TX_OK; } -static int b43legacy_conf_tx(struct ieee80211_hw *hw, - int queue, - const struct ieee80211_tx_queue_params *params) +static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, + int queue, + const struct ieee80211_tx_queue_params *params) { return 0; } -static int b43legacy_get_tx_stats(struct ieee80211_hw *hw, - struct ieee80211_tx_queue_stats *stats) +static int b43legacy_op_get_tx_stats(struct ieee80211_hw *hw, + struct ieee80211_tx_queue_stats *stats) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -2422,8 +2354,8 @@ out: return err; } -static int b43legacy_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) +static int b43legacy_op_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); unsigned long flags; @@ -2572,8 +2504,8 @@ static int b43legacy_antenna_from_ieee80211(u8 antenna) } } -static int b43legacy_dev_config(struct ieee80211_hw *hw, - struct ieee80211_conf *conf) +static int b43legacy_op_dev_config(struct ieee80211_hw *hw, + struct ieee80211_conf *conf) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev; @@ -2634,6 +2566,8 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw, b43legacy_short_slot_timing_disable(dev); } + dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_RADIOTAP); + /* Adjust the desired TX power level. */ if (conf->power_level != 0) { if (conf->power_level != phy->power_level) { @@ -2660,7 +2594,7 @@ static int b43legacy_dev_config(struct ieee80211_hw *hw, " physically off. Press the" " button to turn it on.\n"); } else { - b43legacy_radio_turn_off(dev); + b43legacy_radio_turn_off(dev, 0); b43legacyinfo(dev->wl, "Radio turned off by" " software\n"); } @@ -2676,37 +2610,11 @@ out_unlock_mutex: return err; } -static int b43legacy_dev_set_key(struct ieee80211_hw *hw, - enum set_key_cmd cmd, - const u8 *local_addr, const u8 *addr, - struct ieee80211_key_conf *key) -{ - struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); - struct b43legacy_wldev *dev = wl->current_dev; - unsigned long flags; - int err = -EOPNOTSUPP; - DECLARE_MAC_BUF(mac); - - if (!dev) - return -ENODEV; - mutex_lock(&wl->mutex); - spin_lock_irqsave(&wl->irq_lock, flags); - - if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { - err = -ENODEV; - } - spin_unlock_irqrestore(&wl->irq_lock, flags); - mutex_unlock(&wl->mutex); - b43legacydbg(wl, "Using software based encryption for " - "mac: %s\n", print_mac(mac, addr)); - return err; -} - -static void b43legacy_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, - unsigned int *fflags, - int mc_count, - struct dev_addr_list *mc_list) +static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed, + unsigned int *fflags, + int mc_count, + struct dev_addr_list *mc_list) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -2741,9 +2649,9 @@ static void b43legacy_configure_filter(struct ieee80211_hw *hw, spin_unlock_irqrestore(&wl->irq_lock, flags); } -static int b43legacy_config_interface(struct ieee80211_hw *hw, - int if_id, - struct ieee80211_if_conf *conf) +static int b43legacy_op_config_interface(struct ieee80211_hw *hw, + int if_id, + struct ieee80211_if_conf *conf) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3029,6 +2937,20 @@ static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev) #endif /* CONFIG_SSB_DRIVER_PCICORE */ } +/* Write the short and long frame retry limit values. */ +static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev, + unsigned int short_retry, + unsigned int long_retry) +{ + /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing + * the chip-internal counter. */ + short_retry = min(short_retry, (unsigned int)0xF); + long_retry = min(long_retry, (unsigned int)0xF); + + b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry); + b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry); +} + /* Shutdown a wireless core */ /* Locking: wl->mutex */ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) @@ -3047,11 +2969,15 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) cancel_work_sync(&dev->restart_work); mutex_lock(&wl->mutex); + mutex_unlock(&dev->wl->mutex); + b43legacy_rfkill_exit(dev); + mutex_lock(&dev->wl->mutex); + b43legacy_rng_exit(dev->wl); b43legacy_pio_free(dev); b43legacy_dma_free(dev); b43legacy_chip_exit(dev); - b43legacy_radio_turn_off(dev); + b43legacy_radio_turn_off(dev, 1); b43legacy_switch_analog(dev, 0); if (phy->dyn_tssi_tbl) kfree(phy->tssi2dbm); @@ -3153,7 +3079,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) hf |= B43legacy_HF_SYMW; if (phy->rev == 1) hf |= B43legacy_HF_GDCW; - if (sprom->r1.boardflags_lo & B43legacy_BFL_PACTRL) + if (sprom->boardflags_lo & B43legacy_BFL_PACTRL) hf |= B43legacy_HF_OFDMPABOOST; } else if (phy->type == B43legacy_PHYTYPE_B) { hf |= B43legacy_HF_SYMW; @@ -3162,16 +3088,9 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) } b43legacy_hf_write(dev, hf); - /* Short/Long Retry Limit. - * The retry-limit is a 4-bit counter. Enforce this to avoid overflowing - * the chip-internal counter. - */ - tmp = limit_value(modparam_short_retry, 0, 0xF); - b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, - 0x0006, tmp); - tmp = limit_value(modparam_long_retry, 0, 0xF); - b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, - 0x0007, tmp); + b43legacy_set_retry_limits(dev, + B43legacy_DEFAULT_SHORT_RETRY_LIMIT, + B43legacy_DEFAULT_LONG_RETRY_LIMIT); b43legacy_shm_write16(dev, B43legacy_SHM_SHARED, 0x0044, 3); @@ -3219,6 +3138,7 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) memset(wl->mac_addr, 0, ETH_ALEN); b43legacy_upload_card_macaddress(dev); b43legacy_security_init(dev); + b43legacy_rfkill_init(dev); b43legacy_rng_init(wl); b43legacy_set_status(dev, B43legacy_STAT_INITIALIZED); @@ -3239,8 +3159,8 @@ err_kfree_lo_control: return err; } -static int b43legacy_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +static int b43legacy_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev; @@ -3279,8 +3199,8 @@ static int b43legacy_add_interface(struct ieee80211_hw *hw, return err; } -static void b43legacy_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) +static void b43legacy_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3304,7 +3224,7 @@ static void b43legacy_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&wl->mutex); } -static int b43legacy_start(struct ieee80211_hw *hw) +static int b43legacy_op_start(struct ieee80211_hw *hw) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3335,7 +3255,7 @@ out_mutex_unlock: return err; } -static void b43legacy_stop(struct ieee80211_hw *hw) +static void b43legacy_op_stop(struct ieee80211_hw *hw) { struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); struct b43legacy_wldev *dev = wl->current_dev; @@ -3347,20 +3267,41 @@ static void b43legacy_stop(struct ieee80211_hw *hw) mutex_unlock(&wl->mutex); } +static int b43legacy_op_set_retry_limit(struct ieee80211_hw *hw, + u32 short_retry_limit, + u32 long_retry_limit) +{ + struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); + struct b43legacy_wldev *dev; + int err = 0; + + mutex_lock(&wl->mutex); + dev = wl->current_dev; + if (unlikely(!dev || + (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) { + err = -ENODEV; + goto out_unlock; + } + b43legacy_set_retry_limits(dev, short_retry_limit, long_retry_limit); +out_unlock: + mutex_unlock(&wl->mutex); + + return err; +} static const struct ieee80211_ops b43legacy_hw_ops = { - .tx = b43legacy_tx, - .conf_tx = b43legacy_conf_tx, - .add_interface = b43legacy_add_interface, - .remove_interface = b43legacy_remove_interface, - .config = b43legacy_dev_config, - .config_interface = b43legacy_config_interface, - .set_key = b43legacy_dev_set_key, - .configure_filter = b43legacy_configure_filter, - .get_stats = b43legacy_get_stats, - .get_tx_stats = b43legacy_get_tx_stats, - .start = b43legacy_start, - .stop = b43legacy_stop, + .tx = b43legacy_op_tx, + .conf_tx = b43legacy_op_conf_tx, + .add_interface = b43legacy_op_add_interface, + .remove_interface = b43legacy_op_remove_interface, + .config = b43legacy_op_dev_config, + .config_interface = b43legacy_op_config_interface, + .configure_filter = b43legacy_op_configure_filter, + .get_stats = b43legacy_op_get_stats, + .get_tx_stats = b43legacy_op_get_tx_stats, + .start = b43legacy_op_start, + .stop = b43legacy_op_stop, + .set_retry_limit = b43legacy_op_set_retry_limit, }; /* Hard-reset the chip. Do not call this directly. @@ -3498,18 +3439,13 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) else have_bphy = 1; - /* Initialize LEDs structs. */ - err = b43legacy_leds_init(dev); - if (err) - goto err_powerdown; - dev->phy.gmode = (have_gphy || have_bphy); tmp = dev->phy.gmode ? B43legacy_TMSLOW_GMODE : 0; b43legacy_wireless_core_reset(dev, tmp); err = b43legacy_phy_versioning(dev); if (err) - goto err_leds_exit; + goto err_powerdown; /* Check if this device supports multiband. */ if (!pdev || (pdev->device != 0x4312 && @@ -3535,17 +3471,17 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) err = b43legacy_validate_chipaccess(dev); if (err) - goto err_leds_exit; + goto err_powerdown; err = b43legacy_setup_modes(dev, have_bphy, have_gphy); if (err) - goto err_leds_exit; + goto err_powerdown; /* Now set some default "current_dev" */ if (!wl->current_dev) wl->current_dev = dev; INIT_WORK(&dev->restart_work, b43legacy_chip_reset); - b43legacy_radio_turn_off(dev); + b43legacy_radio_turn_off(dev, 1); b43legacy_switch_analog(dev, 0); ssb_device_disable(dev->dev, 0); ssb_bus_may_powerdown(bus); @@ -3553,8 +3489,6 @@ static int b43legacy_wireless_core_attach(struct b43legacy_wldev *dev) out: return err; -err_leds_exit: - b43legacy_leds_exit(dev); err_powerdown: ssb_bus_may_powerdown(bus); return err; @@ -3637,12 +3571,12 @@ static void b43legacy_sprom_fixup(struct ssb_bus *bus) if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && bus->boardinfo.type == 0x4E && bus->boardinfo.rev > 0x40) - bus->sprom.r1.boardflags_lo |= B43legacy_BFL_PACTRL; + bus->sprom.boardflags_lo |= B43legacy_BFL_PACTRL; /* Convert Antennagain values to Q5.2 */ - if (bus->sprom.r1.antenna_gain_bg == 0xFF) - bus->sprom.r1.antenna_gain_bg = 2; /* if unset, use 2 dBm */ - bus->sprom.r1.antenna_gain_bg <<= 2; + if (bus->sprom.antenna_gain_bg == 0xFF) + bus->sprom.antenna_gain_bg = 2; /* if unset, use 2 dBm */ + bus->sprom.antenna_gain_bg <<= 2; } static void b43legacy_wireless_exit(struct ssb_device *dev, @@ -3677,10 +3611,10 @@ static int b43legacy_wireless_init(struct ssb_device *dev) hw->max_noise = -110; hw->queues = 1; /* FIXME: hardware has more queues */ SET_IEEE80211_DEV(hw, dev->dev); - if (is_valid_ether_addr(sprom->r1.et1mac)) - SET_IEEE80211_PERM_ADDR(hw, sprom->r1.et1mac); + if (is_valid_ether_addr(sprom->et1mac)) + SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); else - SET_IEEE80211_PERM_ADDR(hw, sprom->r1.il0mac); + SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); /* Get and initialize struct b43legacy_wl */ wl = hw_to_b43legacy_wl(hw); diff --git a/drivers/net/wireless/b43legacy/main.h b/drivers/net/wireless/b43legacy/main.h index 68435c5..1f0e2e3 100644 --- a/drivers/net/wireless/b43legacy/main.h +++ b/drivers/net/wireless/b43legacy/main.h @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Copyright (c) 2005 Stefano Brivio + Copyright (c) 2005 Stefano Brivio Copyright (c) 2005, 2006 Michael Buesch Copyright (c) 2005 Danny van Dyk Copyright (c) 2005 Andreas Jaggi diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 491e518..9d527e6 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi @@ -441,7 +441,7 @@ static void b43legacy_phy_inita(struct b43legacy_wldev *dev) might_sleep(); b43legacy_phy_setupg(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_PACTRL) + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) b43legacy_phy_write(dev, 0x046E, 0x03CF); } @@ -543,7 +543,7 @@ static void b43legacy_phy_initb4(struct b43legacy_wldev *dev) if (phy->radio_ver == 0x2050) b43legacy_phy_write(dev, 0x002A, 0x88C2); b43legacy_radio_set_txpower_bg(dev, 0xFFFF, 0xFFFF, 0xFFFF); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI) { + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) { b43legacy_calc_nrssi_slope(dev); b43legacy_calc_nrssi_threshold(dev); } @@ -699,7 +699,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev) b43legacy_radio_write16(dev, 0x005A, 0x0088); b43legacy_radio_write16(dev, 0x005B, 0x006B); b43legacy_radio_write16(dev, 0x005C, 0x000F); - if (dev->dev->bus->sprom.r1.boardflags_lo & 0x8000) { + if (dev->dev->bus->sprom.boardflags_lo & 0x8000) { b43legacy_radio_write16(dev, 0x005D, 0x00FA); b43legacy_radio_write16(dev, 0x005E, 0x00D8); } else { @@ -797,7 +797,7 @@ static void b43legacy_phy_initb6(struct b43legacy_wldev *dev) b43legacy_phy_write(dev, 0x0062, 0x0007); b43legacy_radio_init2050(dev); b43legacy_phy_lo_g_measure(dev); - if (dev->dev->bus->sprom.r1.boardflags_lo & + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) { b43legacy_calc_nrssi_slope(dev); b43legacy_calc_nrssi_threshold(dev); @@ -921,7 +921,7 @@ static void b43legacy_calc_loopback_gain(struct b43legacy_wldev *dev) b43legacy_phy_read(dev, 0x0811) | 0x0100); b43legacy_phy_write(dev, 0x0812, b43legacy_phy_read(dev, 0x0812) & 0xCFFF); - if (dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_EXTLNA) { + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_EXTLNA) { if (phy->rev >= 7) { b43legacy_phy_write(dev, 0x0811, b43legacy_phy_read(dev, 0x0811) @@ -1072,7 +1072,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev) b43legacy_phy_write(dev, 0x0036, (b43legacy_phy_read(dev, 0x0036) & 0x0FFF) | (phy->txctl2 << 12)); - if (dev->dev->bus->sprom.r1.boardflags_lo & + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) b43legacy_phy_write(dev, 0x002E, 0x8075); else @@ -1087,7 +1087,7 @@ static void b43legacy_phy_initg(struct b43legacy_wldev *dev) b43legacy_phy_write(dev, 0x080F, 0x8078); } - if (!(dev->dev->bus->sprom.r1.boardflags_lo & B43legacy_BFL_RSSI)) { + if (!(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI)) { /* The specs state to update the NRSSI LT with * the value 0x7FFFFFFF here. I think that is some weird * compiler optimization in the original driver. @@ -1838,9 +1838,9 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) estimated_pwr = b43legacy_phy_estimate_power_out(dev, average); - max_pwr = dev->dev->bus->sprom.r1.maxpwr_bg; + max_pwr = dev->dev->bus->sprom.maxpwr_bg; - if ((dev->dev->bus->sprom.r1.boardflags_lo + if ((dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) && (phy->type == B43legacy_PHYTYPE_G)) max_pwr -= 0x3; @@ -1848,7 +1848,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) b43legacywarn(dev->wl, "Invalid max-TX-power value in SPROM." "\n"); max_pwr = 74; /* fake it */ - dev->dev->bus->sprom.r1.maxpwr_bg = max_pwr; + dev->dev->bus->sprom.maxpwr_bg = max_pwr; } /* Use regulatory information to get the maximum power. @@ -1858,7 +1858,8 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) * and 1.5 dBm (a safety factor??). The result is in Q5.2 format * which accounts for the factor of 4 */ #define REG_MAX_PWR 20 - max_pwr = min(REG_MAX_PWR * 4 - dev->dev->bus->sprom.r1.antenna_gain_bg + max_pwr = min(REG_MAX_PWR * 4 + - dev->dev->bus->sprom.antenna_gain_bg - 0x6, max_pwr); /* find the desired power in Q5.2 - power_level is in dBm @@ -1918,7 +1919,7 @@ void b43legacy_phy_xmitpower(struct b43legacy_wldev *dev) txpower = 3; radio_attenuation += 2; baseband_attenuation += 2; - } else if (dev->dev->bus->sprom.r1.boardflags_lo + } else if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_PACTRL) { baseband_attenuation += 4 * (radio_attenuation - 2); @@ -2000,9 +2001,9 @@ int b43legacy_phy_init_tssi2dbm_table(struct b43legacy_wldev *dev) B43legacy_WARN_ON(!(phy->type == B43legacy_PHYTYPE_B || phy->type == B43legacy_PHYTYPE_G)); - pab0 = (s16)(dev->dev->bus->sprom.r1.pa0b0); - pab1 = (s16)(dev->dev->bus->sprom.r1.pa0b1); - pab2 = (s16)(dev->dev->bus->sprom.r1.pa0b2); + pab0 = (s16)(dev->dev->bus->sprom.pa0b0); + pab1 = (s16)(dev->dev->bus->sprom.pa0b1); + pab2 = (s16)(dev->dev->bus->sprom.pa0b2); if ((dev->dev->bus->chip_id == 0x4301) && (phy->radio_ver != 0x2050)) { phy->idle_tssi = 0x34; @@ -2013,9 +2014,10 @@ int b43legacy_phy_init_tssi2dbm_table(struct b43legacy_wldev *dev) if (pab0 != 0 && pab1 != 0 && pab2 != 0 && pab0 != -1 && pab1 != -1 && pab2 != -1) { /* The pabX values are set in SPROM. Use them. */ - if ((s8)dev->dev->bus->sprom.r1.itssi_bg != 0 && - (s8)dev->dev->bus->sprom.r1.itssi_bg != -1) - phy->idle_tssi = (s8)(dev->dev->bus->sprom.r1.itssi_bg); + if ((s8)dev->dev->bus->sprom.itssi_bg != 0 && + (s8)dev->dev->bus->sprom.itssi_bg != -1) + phy->idle_tssi = (s8)(dev->dev->bus->sprom. + itssi_bg); else phy->idle_tssi = 62; dyn_tssi2dbm = kmalloc(64, GFP_KERNEL); diff --git a/drivers/net/wireless/b43legacy/phy.h b/drivers/net/wireless/b43legacy/phy.h index f11b427..efa4c5c 100644 --- a/drivers/net/wireless/b43legacy/phy.h +++ b/drivers/net/wireless/b43legacy/phy.h @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c index a361dee..1a72eb0 100644 --- a/drivers/net/wireless/b43legacy/radio.c +++ b/drivers/net/wireless/b43legacy/radio.c @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi @@ -827,7 +827,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) case B43legacy_PHYTYPE_B: { if (phy->radio_ver != 0x2050) return; - if (!(dev->dev->bus->sprom.r1.boardflags_lo & + if (!(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI)) return; @@ -857,7 +857,7 @@ void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev *dev) } case B43legacy_PHYTYPE_G: if (!phy->gmode || - !(dev->dev->bus->sprom.r1.boardflags_lo & + !(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI)) { tmp16 = b43legacy_nrssi_hw_read(dev, 0x20); if (tmp16 >= 0x20) @@ -1406,7 +1406,7 @@ static u16 b43legacy_get_812_value(struct b43legacy_wldev *dev, u8 lpd) if (!phy->gmode) return 0; if (!has_loopback_gain(phy)) { - if (phy->rev < 7 || !(dev->dev->bus->sprom.r1.boardflags_lo + if (phy->rev < 7 || !(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_EXTLNA)) { switch (lpd) { case LPD(0, 1, 1): @@ -1459,7 +1459,7 @@ static u16 b43legacy_get_812_value(struct b43legacy_wldev *dev, u8 lpd) } loop_or = (loop << 8) | extern_lna_control; - if (phy->rev >= 7 && dev->dev->bus->sprom.r1.boardflags_lo + if (phy->rev >= 7 && dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_EXTLNA) { if (extern_lna_control) loop_or |= 0x8000; @@ -1550,7 +1550,7 @@ u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev) b43legacy_get_812_value(dev, LPD(0, 1, 1))); if (phy->rev < 7 || - !(dev->dev->bus->sprom.r1.boardflags_lo + !(dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_EXTLNA)) b43legacy_phy_write(dev, 0x0811, 0x01B3); else @@ -1786,7 +1786,7 @@ int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, channel2freq_bg(channel)); if (channel == 14) { - if (dev->dev->bus->sprom.r1.country_code == 5) /* JAPAN) */ + if (dev->dev->bus->sprom.country_code == 5) /* JAPAN) */ b43legacy_shm_write32(dev, B43legacy_SHM_SHARED, B43legacy_UCODEFLAGS_OFFSET, b43legacy_shm_read32(dev, @@ -2113,21 +2113,25 @@ void b43legacy_radio_turn_on(struct b43legacy_wldev *dev) B43legacy_BUG_ON(1); } phy->radio_on = 1; - b43legacy_leds_update(dev, 0); } -void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) +void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force) { struct b43legacy_phy *phy = &dev->phy; + if (!phy->radio_on && !force) + return; + if (phy->type == B43legacy_PHYTYPE_G && dev->dev->id.revision >= 5) { u16 rfover, rfoverval; rfover = b43legacy_phy_read(dev, B43legacy_PHY_RFOVER); rfoverval = b43legacy_phy_read(dev, B43legacy_PHY_RFOVERVAL); - phy->radio_off_context.rfover = rfover; - phy->radio_off_context.rfoverval = rfoverval; - phy->radio_off_context.valid = 1; + if (!force) { + phy->radio_off_context.rfover = rfover; + phy->radio_off_context.rfoverval = rfoverval; + phy->radio_off_context.valid = 1; + } b43legacy_phy_write(dev, B43legacy_PHY_RFOVER, rfover | 0x008C); b43legacy_phy_write(dev, B43legacy_PHY_RFOVERVAL, rfoverval & 0xFF73); @@ -2135,7 +2139,6 @@ void b43legacy_radio_turn_off(struct b43legacy_wldev *dev) b43legacy_phy_write(dev, 0x0015, 0xAA00); phy->radio_on = 0; b43legacydbg(dev->wl, "Radio initialized\n"); - b43legacy_leds_update(dev, 0); } void b43legacy_radio_clear_tssi(struct b43legacy_wldev *dev) diff --git a/drivers/net/wireless/b43legacy/radio.h b/drivers/net/wireless/b43legacy/radio.h index 6c6a203..ec4de28 100644 --- a/drivers/net/wireless/b43legacy/radio.h +++ b/drivers/net/wireless/b43legacy/radio.h @@ -3,7 +3,7 @@ Broadcom B43legacy wireless driver Copyright (c) 2005 Martin Langer , - Stefano Brivio + Stefano Brivio Michael Buesch Danny van Dyk Andreas Jaggi @@ -61,7 +61,7 @@ void b43legacy_radio_write16(struct b43legacy_wldev *dev, u16 offset, u16 val); u16 b43legacy_radio_init2050(struct b43legacy_wldev *dev); void b43legacy_radio_turn_on(struct b43legacy_wldev *dev); -void b43legacy_radio_turn_off(struct b43legacy_wldev *dev); +void b43legacy_radio_turn_off(struct b43legacy_wldev *dev, bool force); int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, u8 channel, int synthetic_pu_workaround); diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c new file mode 100644 index 0000000..b9d38a4 --- /dev/null +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -0,0 +1,189 @@ +/* + + Broadcom B43 wireless driver + RFKILL support + + Copyright (c) 2007 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 "rfkill.h" +#include "radio.h" +#include "b43legacy.h" + + +/* Returns TRUE, if the radio is enabled in hardware. */ +static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) +{ + if (dev->phy.rev >= 3) { + if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) + & B43legacy_MMIO_RADIO_HWENABLED_HI_MASK)) + return 1; + } else { + if (b43legacy_read16(dev, B43legacy_MMIO_RADIO_HWENABLED_LO) + & B43legacy_MMIO_RADIO_HWENABLED_LO_MASK) + return 1; + } + return 0; +} + +/* The poll callback for the hardware button. */ +static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) +{ + struct b43legacy_wldev *dev = poll_dev->private; + struct b43legacy_wl *wl = dev->wl; + bool enabled; + bool report_change = 0; + + mutex_lock(&wl->mutex); + B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED); + enabled = b43legacy_is_hw_radio_enabled(dev); + if (unlikely(enabled != dev->radio_hw_enable)) { + dev->radio_hw_enable = enabled; + report_change = 1; + b43legacyinfo(wl, "Radio hardware status changed to %s\n", + enabled ? "ENABLED" : "DISABLED"); + } + mutex_unlock(&wl->mutex); + + if (unlikely(report_change)) + input_report_key(poll_dev->input, KEY_WLAN, enabled); +} + +/* Called when the RFKILL toggled in software. + * This is called without locking. */ +static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) +{ + struct b43legacy_wldev *dev = data; + struct b43legacy_wl *wl = dev->wl; + int err = 0; + + if (!wl->rfkill.registered) + return 0; + + mutex_lock(&wl->mutex); + B43legacy_WARN_ON(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED); + switch (state) { + case RFKILL_STATE_ON: + if (!dev->radio_hw_enable) { + /* No luck. We can't toggle the hardware RF-kill + * button from software. */ + err = -EBUSY; + goto out_unlock; + } + if (!dev->phy.radio_on) + b43legacy_radio_turn_on(dev); + break; + case RFKILL_STATE_OFF: + if (dev->phy.radio_on) + b43legacy_radio_turn_off(dev, 0); + break; + } + +out_unlock: + mutex_unlock(&wl->mutex); + + return err; +} + +char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + + if (!wl->rfkill.rfkill) + return NULL; + return rfkill_get_led_name(wl->rfkill.rfkill); +} + +void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + struct b43legacy_rfkill *rfk = &(wl->rfkill); + int err; + + if (rfk->rfkill) { + err = rfkill_register(rfk->rfkill); + if (err) { + b43legacywarn(wl, "Failed to register RF-kill button\n"); + goto err_free_rfk; + } + } + if (rfk->poll_dev) { + err = input_register_polled_device(rfk->poll_dev); + if (err) { + b43legacywarn(wl, "Failed to register RF-kill polldev\n"); + goto err_free_polldev; + } + } + + return; +err_free_rfk: + rfkill_free(rfk->rfkill); + rfk->rfkill = NULL; +err_free_polldev: + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +} + +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + if (rfk->poll_dev) + input_unregister_polled_device(rfk->poll_dev); + if (rfk->rfkill) + rfkill_unregister(rfk->rfkill); +} + +void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) +{ + struct b43legacy_wl *wl = dev->wl; + struct b43legacy_rfkill *rfk = &(wl->rfkill); + + snprintf(rfk->name, sizeof(rfk->name), + "b43legacy-%s", wiphy_name(wl->hw->wiphy)); + + rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); + if (!rfk->rfkill) { + b43legacywarn(wl, "Failed to allocate RF-kill button\n"); + return; + } + rfk->rfkill->name = rfk->name; + rfk->rfkill->state = RFKILL_STATE_ON; + rfk->rfkill->data = dev; + rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; + rfk->rfkill->user_claim_unsupported = 1; + + rfk->poll_dev = input_allocate_polled_device(); + if (rfk->poll_dev) { + rfk->poll_dev->private = dev; + rfk->poll_dev->poll = b43legacy_rfkill_poll; + rfk->poll_dev->poll_interval = 1000; /* msecs */ + } else + b43legacywarn(wl, "Failed to allocate RF-kill polldev\n"); +} + +void b43legacy_rfkill_free(struct b43legacy_wldev *dev) +{ + struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); + + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; + rfkill_free(rfk->rfkill); + rfk->rfkill = NULL; +} diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h new file mode 100644 index 0000000..11150a8 --- /dev/null +++ b/drivers/net/wireless/b43legacy/rfkill.h @@ -0,0 +1,59 @@ +#ifndef B43legacy_RFKILL_H_ +#define B43legacy_RFKILL_H_ + +struct b43legacy_wldev; + +#ifdef CONFIG_B43LEGACY_RFKILL + +#include +#include +#include + + + +struct b43legacy_rfkill { + /* The RFKILL subsystem data structure */ + struct rfkill *rfkill; + /* The poll device for the RFKILL input button */ + struct input_polled_dev *poll_dev; + /* Did initialization succeed? Used for freeing. */ + bool registered; + /* The unique name of this rfkill switch */ + char name[sizeof("b43legacy-phy4294967295")]; +}; + +/* The init function returns void, because we are not interested + * in failing the b43 init process when rfkill init failed. */ +void b43legacy_rfkill_init(struct b43legacy_wldev *dev); +void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); + +char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); + + +#else /* CONFIG_B43LEGACY_RFKILL */ +/* No RFKILL support. */ + +struct b43legacy_rfkill { + /* empty */ +}; + +static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) +{ +} +static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) +{ +} +static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) +{ + return NULL; +} + +#endif /* CONFIG_B43LEGACY_RFKILL */ + +#endif /* B43legacy_RFKILL_H_ */ diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index fa1e656..1e4b879 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -5,7 +5,7 @@ Transmission (TX/RX) related functions. Copyright (C) 2005 Martin Langer - Copyright (C) 2005 Stefano Brivio + Copyright (C) 2005 Stefano Brivio Copyright (C) 2005, 2006 Michael Buesch Copyright (C) 2005 Danny van Dyk Copyright (C) 2005 Andreas Jaggi @@ -290,6 +290,8 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev, mac_ctl |= B43legacy_TX4_MAC_STMSDU; if (rate_fb_ofdm) mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM; + if (txctl->flags & IEEE80211_TXCTL_LONG_RETRY_LIMIT) + mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; /* Generate the RTS or CTS-to-self frame */ if ((txctl->flags & IEEE80211_TXCTL_USE_RTS_CTS) || @@ -335,7 +337,6 @@ static void generate_txhdr_fw3(struct b43legacy_wldev *dev, len, rts_rate_fb); hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame); txhdr->rts_dur_fb = hdr->duration_id; - mac_ctl |= B43legacy_TX4_MAC_LONGFRAME; } /* Magic cookie */ @@ -378,7 +379,7 @@ static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev, else tmp -= 3; } else { - if (dev->dev->bus->sprom.r1.boardflags_lo + if (dev->dev->bus->sprom.boardflags_lo & B43legacy_BFL_RSSI) { if (in_rssi > 63) in_rssi = 63; @@ -531,7 +532,23 @@ void b43legacy_rx(struct b43legacy_wldev *dev, else status.rate = b43legacy_plcp_get_bitrate_cck(plcp); status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT); - status.mactime = mactime; + + /* + * If monitors are present get full 64-bit timestamp. This + * code assumes we get to process the packet within 16 bits + * of timestamp, i.e. about 65 milliseconds after the PHY + * received the first symbol. + */ + if (dev->wl->radiotap_enabled) { + u16 low_mactime_now; + + b43legacy_tsf_read(dev, &status.mactime); + low_mactime_now = status.mactime; + status.mactime = status.mactime & ~0xFFFFULL; + status.mactime += mactime; + if (low_mactime_now <= mactime) + status.mactime -= 0x10000; + } chanid = (chanstat & B43legacy_RX_CHAN_ID) >> B43legacy_RX_CHAN_ID_SHIFT; diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index c592641..286b46c 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2624,7 +2624,7 @@ static void prism2_check_magic(local_info_t *local) /* Called only from hardware IRQ */ static irqreturn_t prism2_interrupt(int irq, void *dev_id) { - struct net_device *dev = (struct net_device *) dev_id; + struct net_device *dev = dev_id; struct hostap_interface *iface; local_info_t *local; int events = 0; diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index fc6cdd8..dc3813b 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c @@ -6591,8 +6591,7 @@ static const long ipw2100_frequencies[] = { 2472, 2484 }; -#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \ - sizeof(ipw2100_frequencies[0])) +#define FREQ_COUNT ARRAY_SIZE(ipw2100_frequencies) static const long ipw2100_rates_11b[] = { 1000000, diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 8d52a26..c91e5f9 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -1,24 +1,66 @@ -config IWLWIFI - bool "Intel Wireless WiFi Link Drivers" +config IWL4965 + tristate "Intel Wireless WiFi 4965AGN" depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL select FW_LOADER - default n ---help--- - Select to enable drivers based on the iwlwifi project. This - project provides a common foundation for Intel's wireless - drivers designed to use the mac80211 subsystem. + Select to build the driver supporting the: + + Intel Wireless WiFi Link 4965AGN + + This driver uses the kernel's mac80211 subsystem. See for information on the capabilities currently enabled in this - driver and for tips for debugging issues and problems. + driver and for tips for debugging any issues or problems. + + In order to use this driver, you will need a microcode (uCode) + image for it. You can obtain the microcode from: + + . + + See the above referenced README.iwlwifi for information on where + to install the microcode images. + + If you want to compile the driver as a module ( = code which can be + inserted in and remvoed from the running kernel whenever you want), + say M here and read . The + module will be called iwl4965.ko. + +config IWL4965_QOS + bool "Enable Wireless QoS in iwl4965 driver" + depends on IWL4965 + ---help--- + This option will enable wireless quality of service (QoS) for the + iw4965 driver. + +config IWL4965_HT + bool "Enable 802.11n HT features in iwl4965 driver" + depends on EXPERIMENTAL + depends on IWL4965 && IWL4965_QOS + depends on n + ---help--- + This option enables IEEE 802.11n High Throughput features + for the iwl4965 driver. -config IWLWIFI_DEBUG - bool "Enable full debugging output in iwlwifi drivers" - depends on IWLWIFI - default y +config IWL4965_SPECTRUM_MEASUREMENT + bool "Enable Spectrum Measurement in iw4965 driver" + depends on IWL4965 ---help--- - This option will enable debug tracing output for the iwlwifi - drivers. + This option will enable spectrum measurement for the iwl4965 driver. + +config IWL4965_SENSITIVITY + bool "Enable Sensitivity Calibration in iwl4965 driver" + depends on IWL4965 + ---help--- + This option will enable sensitivity calibration for the iwl4965 + driver. + +config IWL4965_DEBUG + bool "Enable full debugging output in iwl4965 driver" + depends on IWL4965 + ---help--- + This option will enable debug tracing output for the iwl4965 + driver. This will result in the kernel module being ~100k larger. You can control which debug output is sent to the kernel log by setting the @@ -33,52 +75,20 @@ config IWLWIFI_DEBUG % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level You can find the list of debug mask values in: - drivers/net/wireless/mac80211/iwlwifi/iwl-debug.h + drivers/net/wireless/iwlwifi/iwl-4965-debug.h If this is your first time using this driver, you should say Y here as the debug information can assist others in helping you resolve any problems you may encounter. -config IWLWIFI_SENSITIVITY - bool "Enable Sensitivity Calibration in iwlwifi drivers" - depends on IWLWIFI - default y - ---help--- - This option will enable sensitivity calibration for the iwlwifi - drivers. - -config IWLWIFI_SPECTRUM_MEASUREMENT - bool "Enable Spectrum Measurement in iwlwifi drivers" - depends on IWLWIFI - default y - ---help--- - This option will enable spectrum measurement for the iwlwifi drivers. - -config IWLWIFI_QOS - bool "Enable Wireless QoS in iwlwifi drivers" - depends on IWLWIFI - default y - ---help--- - This option will enable wireless quality of service (QoS) for the - iwlwifi drivers. - -config IWLWIFI_HT - bool "Enable 802.11n HT features in iwlwifi drivers" - depends on EXPERIMENTAL - depends on IWLWIFI && MAC80211_HT - default n - ---help--- - This option enables IEEE 802.11n High Throughput features - for the iwlwifi drivers. - -config IWL4965 - tristate "Intel Wireless WiFi 4965AGN" - depends on m && IWLWIFI && EXPERIMENTAL - default m +config IWL3945 + tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" + depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL + select FW_LOADER ---help--- Select to build the driver supporting the: - Intel Wireless WiFi Link 4965AGN + Intel PRO/Wireless 3945ABG/BG Network Connection This driver uses the kernel's mac80211 subsystem. @@ -97,32 +107,44 @@ config IWL4965 If you want to compile the driver as a module ( = code which can be inserted in and remvoed from the running kernel whenever you want), say M here and read . The - module will be called iwl4965.ko. + module will be called iwl3945.ko. -config IWL3945 - tristate "Intel PRO/Wireless 3945ABG/BG Network Connection" - depends on m && IWLWIFI && EXPERIMENTAL - default m +config IWL3945_QOS + bool "Enable Wireless QoS in iwl3945 driver" + depends on IWL3945 ---help--- - Select to build the driver supporting the: + This option will enable wireless quality of service (QoS) for the + iwl3945 driver. - Intel PRO/Wireless 3945ABG/BG Network Connection +config IWL3945_SPECTRUM_MEASUREMENT + bool "Enable Spectrum Measurement in iwl3945 drivers" + depends on IWL3945 + ---help--- + This option will enable spectrum measurement for the iwl3945 driver. - This driver uses the kernel's mac80211 subsystem. +config IWL3945_DEBUG + bool "Enable full debugging output in iwl3945 driver" + depends on IWL3945 + ---help--- + This option will enable debug tracing output for the iwl3945 + driver. - See for - information on the capabilities currently enabled in this - driver and for tips for debugging any issues or problems. + This will result in the kernel module being ~100k larger. You can + control which debug output is sent to the kernel log by setting the + value in - In order to use this driver, you will need a microcode (uCode) - image for it. You can obtain the microcode from: + /sys/bus/pci/drivers/${DRIVER}/debug_level - . + This entry will only exist if this option is enabled. - See the above referenced README.iwlwifi for information on where - to install the microcode images. + To set a value, simply echo an 8-byte hex value to the same file: + + % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level + + You can find the list of debug mask values in: + drivers/net/wireless/iwlwifi/iwl-3945-debug.h + + If this is your first time using this driver, you should say Y here + as the debug information can assist others in helping you resolve + any problems you may encounter. - If you want to compile the driver as a module ( = code which can be - inserted in and remvoed from the running kernel whenever you want), - say M here and read . The - module will be called iwl3945.ko. diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-commands.h b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h new file mode 100644 index 0000000..3cac2c8 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-commands.h @@ -0,0 +1,1639 @@ +/****************************************************************************** + * + * 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) 2005 - 2007 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2007 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. + * + *****************************************************************************/ +/* + * Please use this file (iwl-3945-commands.h) only for uCode API definitions. + * Please use iwl-3945-hw.h for hardware-related definitions. + * Please use iwl-3945.h for driver implementation definitions. + */ + +#ifndef __iwl_3945_commands_h__ +#define __iwl_3945_commands_h__ + +enum { + REPLY_ALIVE = 0x1, + REPLY_ERROR = 0x2, + + /* RXON and QOS commands */ + REPLY_RXON = 0x10, + REPLY_RXON_ASSOC = 0x11, + REPLY_QOS_PARAM = 0x13, + REPLY_RXON_TIMING = 0x14, + + /* Multi-Station support */ + REPLY_ADD_STA = 0x18, + REPLY_REMOVE_STA = 0x19, /* not used */ + REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ + + /* RX, TX, LEDs */ + REPLY_3945_RX = 0x1b, /* 3945 only */ + REPLY_TX = 0x1c, + REPLY_RATE_SCALE = 0x47, /* 3945 only */ + REPLY_LEDS_CMD = 0x48, + REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ + + /* 802.11h related */ + RADAR_NOTIFICATION = 0x70, /* not used */ + REPLY_QUIET_CMD = 0x71, /* not used */ + REPLY_CHANNEL_SWITCH = 0x72, + CHANNEL_SWITCH_NOTIFICATION = 0x73, + REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, + SPECTRUM_MEASURE_NOTIFICATION = 0x75, + + /* Power Management */ + POWER_TABLE_CMD = 0x77, + PM_SLEEP_NOTIFICATION = 0x7A, + PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, + + /* Scan commands and notifications */ + REPLY_SCAN_CMD = 0x80, + REPLY_SCAN_ABORT_CMD = 0x81, + SCAN_START_NOTIFICATION = 0x82, + SCAN_RESULTS_NOTIFICATION = 0x83, + SCAN_COMPLETE_NOTIFICATION = 0x84, + + /* IBSS/AP commands */ + BEACON_NOTIFICATION = 0x90, + REPLY_TX_BEACON = 0x91, + WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ + + /* Miscellaneous commands */ + QUIET_NOTIFICATION = 0x96, /* not used */ + REPLY_TX_PWR_TABLE_CMD = 0x97, + MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ + + /* Bluetooth device coexistance config command */ + REPLY_BT_CONFIG = 0x9b, + + /* Statistics */ + REPLY_STATISTICS_CMD = 0x9c, + STATISTICS_NOTIFICATION = 0x9d, + + /* RF-KILL commands and notifications */ + REPLY_CARD_STATE_CMD = 0xa0, + CARD_STATE_NOTIFICATION = 0xa1, + + /* Missed beacons notification */ + MISSED_BEACONS_NOTIFICATION = 0xa2, + + REPLY_MAX = 0xff +}; + +/****************************************************************************** + * (0) + * Commonly used structures and definitions: + * Command header, txpower + * + *****************************************************************************/ + +/* iwl3945_cmd_header flags value */ +#define IWL_CMD_FAILED_MSK 0x40 + +/** + * struct iwl3945_cmd_header + * + * This header format appears in the beginning of each command sent from the + * driver, and each response/notification received from uCode. + */ +struct iwl3945_cmd_header { + u8 cmd; /* Command ID: REPLY_RXON, etc. */ + u8 flags; /* IWL_CMD_* */ + /* + * The driver sets up the sequence number to values of its chosing. + * uCode does not use this value, but passes it back to the driver + * when sending the response to each driver-originated command, so + * the driver can match the response to the command. Since the values + * don't get used by uCode, the driver may set up an arbitrary format. + * + * There is one exception: uCode sets bit 15 when it originates + * the response/notification, i.e. when the response/notification + * is not a direct response to a command sent by the driver. For + * example, uCode issues REPLY_3945_RX when it sends a received frame + * to the driver; it is not a direct response to any driver command. + * + * The Linux driver uses the following format: + * + * 0:7 index/position within Tx queue + * 8:13 Tx queue selection + * 14:14 driver sets this to indicate command is in the 'huge' + * storage at the end of the command buffers, i.e. scan cmd + * 15:15 uCode sets this in uCode-originated response/notification + */ + __le16 sequence; + + /* command or response/notification data follows immediately */ + u8 data[0]; +} __attribute__ ((packed)); + +/** + * struct iwl3945_tx_power + * + * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH + * + * Each entry contains two values: + * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained + * linear value that multiplies the output of the digital signal processor, + * before being sent to the analog radio. + * 2) Radio gain. This sets the analog gain of the radio Tx path. + * It is a coarser setting, and behaves in a logarithmic (dB) fashion. + * + * Driver obtains values from struct iwl3945_tx_power power_gain_table[][]. + */ +struct iwl3945_tx_power { + u8 tx_gain; /* gain for analog radio */ + u8 dsp_atten; /* gain for DSP */ +} __attribute__ ((packed)); + +/** + * struct iwl3945_power_per_rate + * + * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + */ +struct iwl3945_power_per_rate { + u8 rate; /* plcp */ + struct iwl3945_tx_power tpc; + u8 reserved; +} __attribute__ ((packed)); + +/****************************************************************************** + * (0a) + * Alive and Error Commands & Responses: + * + *****************************************************************************/ + +#define UCODE_VALID_OK __constant_cpu_to_le32(0x1) +#define INITIALIZE_SUBTYPE (9) + +/* + * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "initialize alive" notification once the initialization + * uCode image has completed its work, and is ready to load the runtime image. + * This is the *first* "alive" notification that the driver will receive after + * rebooting uCode; the "initialize" alive is indicated by subtype field == 9. + * + * See comments documenting "BSM" (bootstrap state machine). + */ +struct iwl3945_init_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* "9" for initialize alive */ + __le16 reserved2; + __le32 log_event_table_ptr; + __le32 error_event_table_ptr; + __le32 timestamp; + __le32 is_valid; +} __attribute__ ((packed)); + + +/** + * REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "alive" notification once the runtime image is ready + * to receive commands from the driver. This is the *second* "alive" + * notification that the driver will receive after rebooting uCode; + * this "alive" is indicated by subtype field != 9. + * + * See comments documenting "BSM" (bootstrap state machine). + * + * This response includes two pointers to structures within the device's + * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: + * + * 1) log_event_table_ptr indicates base of the event log. This traces + * a 256-entry history of uCode execution within a circular buffer. + * + * 2) error_event_table_ptr indicates base of the error log. This contains + * information about any uCode error that occurs. + * + * The Linux driver can print both logs to the system log when a uCode error + * occurs. + */ +struct iwl3945_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* not "9" for runtime alive */ + __le16 reserved2; + __le32 log_event_table_ptr; /* SRAM address for event log */ + __le32 error_event_table_ptr; /* SRAM address for error log */ + __le32 timestamp; + __le32 is_valid; +} __attribute__ ((packed)); + +union tsf { + u8 byte[8]; + __le16 word[4]; + __le32 dw[2]; +}; + +/* + * REPLY_ERROR = 0x2 (response only, not a command) + */ +struct iwl3945_error_resp { + __le32 error_type; + u8 cmd_id; + u8 reserved1; + __le16 bad_cmd_seq_num; + __le16 reserved2; + __le32 error_info; + union tsf timestamp; +} __attribute__ ((packed)); + +/****************************************************************************** + * (1) + * RXON Commands & Responses: + * + *****************************************************************************/ + +/* + * Rx config defines & structure + */ +/* rx_config device types */ +enum { + RXON_DEV_TYPE_AP = 1, + RXON_DEV_TYPE_ESS = 3, + RXON_DEV_TYPE_IBSS = 4, + RXON_DEV_TYPE_SNIFFER = 6, +}; + +/* rx_config flags */ +/* band & modulation selection */ +#define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) +#define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) +/* auto detection enable */ +#define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) +/* TGg protection when tx */ +#define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) +/* cck short slot & preamble */ +#define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) +#define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) +/* antenna selection */ +#define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) +#define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) +#define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) +#define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) +/* radar detection enable */ +#define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) +#define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) +/* rx response to host with 8-byte TSF +* (according to ON_AIR deassertion) */ +#define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) + +/* rx_config filter flags */ +/* accept all data frames */ +#define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) +/* pass control & management to host */ +#define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) +/* accept multi-cast */ +#define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) +/* don't decrypt uni-cast frames */ +#define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) +/* don't decrypt multi-cast frames */ +#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) +/* STA is associated */ +#define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) +/* transfer to host non bssid beacons in associated state */ +#define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) + +/** + * REPLY_RXON = 0x10 (command, has simple generic response) + * + * RXON tunes the radio tuner to a service channel, and sets up a number + * of parameters that are used primarily for Rx, but also for Tx operations. + * + * NOTE: When tuning to a new channel, driver must set the + * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent + * info within the device, including the station tables, tx retry + * rate tables, and txpower tables. Driver must build a new station + * table and txpower table before transmitting anything on the RXON + * channel. + * + * NOTE: All RXONs wipe clean the internal txpower table. Driver must + * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), + * regardless of whether RXON_FILTER_ASSOC_MSK is set. + */ +struct iwl3945_rxon_cmd { + u8 node_addr[6]; + __le16 reserved1; + u8 bssid_addr[6]; + __le16 reserved2; + u8 wlap_bssid_addr[6]; + __le16 reserved3; + u8 dev_type; + u8 air_propagation; + __le16 reserved4; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 assoc_id; + __le32 flags; + __le32 filter_flags; + __le16 channel; + __le16 reserved5; +} __attribute__ ((packed)); + +/* + * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) + */ +struct iwl3945_rxon_assoc_cmd { + __le32 flags; + __le32 filter_flags; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) + */ +struct iwl3945_rxon_time_cmd { + union tsf timestamp; + __le16 beacon_interval; + __le16 atim_window; + __le32 beacon_init_val; + __le16 listen_interval; + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) + */ +struct iwl3945_channel_switch_cmd { + u8 band; + u8 expect_beacon; + __le16 channel; + __le32 rxon_flags; + __le32 rxon_filter_flags; + __le32 switch_time; + struct iwl3945_power_per_rate power[IWL_MAX_RATES]; +} __attribute__ ((packed)); + +/* + * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) + */ +struct iwl3945_csa_notification { + __le16 band; + __le16 channel; + __le32 status; /* 0 - OK, 1 - fail */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (2) + * Quality-of-Service (QOS) Commands & Responses: + * + *****************************************************************************/ + +/** + * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM + * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd + * + * @cw_min: Contention window, start value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x0f. + * @cw_max: Contention window, max value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x3f. + * @aifsn: Number of slots in Arbitration Interframe Space (before + * performing random backoff timing prior to Tx). Device default 1. + * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. + * + * Device will automatically increase contention window by (2*CW) + 1 for each + * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW + * value, to cap the CW value. + */ +struct iwl3945_ac_qos { + __le16 cw_min; + __le16 cw_max; + u8 aifsn; + u8 reserved1; + __le16 edca_txop; +} __attribute__ ((packed)); + +/* QoS flags defines */ +#define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) +#define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) +#define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) + +/* Number of Access Categories (AC) (EDCA), queues 0..3 */ +#define AC_NUM 4 + +/* + * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) + * + * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs + * 0: Background, 1: Best Effort, 2: Video, 3: Voice. + */ +struct iwl3945_qosparam_cmd { + __le32 qos_flags; + struct iwl3945_ac_qos ac[AC_NUM]; +} __attribute__ ((packed)); + +/****************************************************************************** + * (3) + * Add/Modify Stations Commands & Responses: + * + *****************************************************************************/ +/* + * Multi station support + */ + +/* Special, dedicated locations within device's station table */ +#define IWL_AP_ID 0 +#define IWL_MULTICAST_ID 1 +#define IWL_STA_ID 2 +#define IWL3945_BROADCAST_ID 24 +#define IWL3945_STATION_COUNT 25 + +#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ +#define IWL_INVALID_STATION 255 + +#define STA_FLG_TX_RATE_MSK __constant_cpu_to_le32(1<<2); +#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1<<8); + +/* Use in mode field. 1: modify existing entry, 0: add new station entry */ +#define STA_CONTROL_MODIFY_MSK 0x01 + +/* key flags __le16*/ +#define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) +#define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) +#define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) +#define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) +#define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) + +#define STA_KEY_FLG_KEYID_POS 8 +#define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) + +/* Flags indicate whether to modify vs. don't change various station params */ +#define STA_MODIFY_KEY_MASK 0x01 +#define STA_MODIFY_TID_DISABLE_TX 0x02 +#define STA_MODIFY_TX_RATE_MSK 0x04 + +/* + * Antenna masks: + * bit14:15 01 B inactive, A active + * 10 B active, A inactive + * 11 Both active + */ +#define RATE_MCS_ANT_A_POS 14 +#define RATE_MCS_ANT_B_POS 15 +#define RATE_MCS_ANT_A_MSK 0x4000 +#define RATE_MCS_ANT_B_MSK 0x8000 +#define RATE_MCS_ANT_AB_MSK 0xc000 + +struct iwl3945_keyinfo { + __le16 key_flags; + u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ + u8 reserved1; + __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ + __le16 reserved2; + u8 key[16]; /* 16-byte unicast decryption key */ +} __attribute__ ((packed)); + +/** + * struct sta_id_modify + * @addr[ETH_ALEN]: station's MAC address + * @sta_id: index of station in uCode's station table + * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change + * + * Driver selects unused table index when adding new station, + * or the index to a pre-existing station entry when modifying that station. + * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). + * + * modify_mask flags select which parameters to modify vs. leave alone. + */ +struct sta_id_modify { + u8 addr[ETH_ALEN]; + __le16 reserved1; + u8 sta_id; + u8 modify_mask; + __le16 reserved2; +} __attribute__ ((packed)); + +/* + * REPLY_ADD_STA = 0x18 (command) + * + * 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, + * 3945 uses REPLY_RATE_SCALE to set up rate tables). + * + * REPLY_ADD_STA sets up the table entry for one station, either creating + * a new entry, or modifying a pre-existing one. + * + * NOTE: RXON command (without "associated" bit set) wipes the station table + * clean. Moving into RF_KILL state does this also. Driver must set up + * new station table before transmitting anything on the RXON channel + * (except active scans or active measurements; those commands carry + * their own txpower/rate setup data). + * + * When getting started on a new channel, driver must set up the + * IWL_BROADCAST_ID entry (last entry in the table). For a client + * station in a BSS, once an AP is selected, driver sets up the AP STA + * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP + * are all that are needed for a BSS client station. If the device is + * used as AP, or in an IBSS network, driver must set up station table + * entries for all STAs in network, starting with index IWL_STA_ID. + */ +struct iwl3945_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl3945_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 rate_n_flags; + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; +} __attribute__ ((packed)); + +#define ADD_STA_SUCCESS_MSK 0x1 +#define ADD_STA_NO_ROOM_IN_TABLE 0x2 +#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 +/* + * REPLY_ADD_STA = 0x18 (response) + */ +struct iwl3945_add_sta_resp { + u8 status; /* ADD_STA_* */ +} __attribute__ ((packed)); + + +/****************************************************************************** + * (4) + * Rx Responses: + * + *****************************************************************************/ + +struct iwl3945_rx_frame_stats { + u8 phy_count; + u8 id; + u8 rssi; + u8 agc; + __le16 sig_avg; + __le16 noise_diff; + u8 payload[0]; +} __attribute__ ((packed)); + +struct iwl3945_rx_frame_hdr { + __le16 channel; + __le16 phy_flags; + u8 reserved1; + u8 rate; + __le16 len; + u8 payload[0]; +} __attribute__ ((packed)); + +#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) +#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) + +#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) +#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) +#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) +#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) +#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) + +#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) +#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) +#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) +#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) +#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) + +#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) +#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) +#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) +#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) +#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) + +struct iwl3945_rx_frame_end { + __le32 status; + __le64 timestamp; + __le32 beacon_timestamp; +} __attribute__ ((packed)); + +/* + * REPLY_3945_RX = 0x1b (response only, not a command) + * + * NOTE: DO NOT dereference from casts to this structure + * It is provided only for calculating minimum data set size. + * The actual offsets of the hdr and end are dynamic based on + * stats.phy_count + */ +struct iwl3945_rx_frame { + struct iwl3945_rx_frame_stats stats; + struct iwl3945_rx_frame_hdr hdr; + struct iwl3945_rx_frame_end end; +} __attribute__ ((packed)); + +/* Fixed (non-configurable) rx data from phy */ +#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4) +#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70) +#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ +#define IWL_AGC_DB_POS (7) +struct iwl4965_rx_non_cfg_phy { + __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ + __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ + u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ + u8 pad[0]; +} __attribute__ ((packed)); + +/* + * REPLY_4965_RX = 0xc3 (response only, not a command) + * Used only for legacy (non 11n) frames. + */ +#define RX_RES_PHY_CNT 14 +struct iwl4965_rx_phy_res { + u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ + u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ + u8 stat_id; /* configurable DSP phy data set ID */ + u8 reserved1; + __le64 timestamp; /* TSF at on air rise */ + __le32 beacon_time_stamp; /* beacon at on-air rise */ + __le16 phy_flags; /* general phy flags: band, modulation, ... */ + __le16 channel; /* channel number */ + __le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */ + __le32 reserved2; + __le32 rate_n_flags; + __le16 byte_count; /* frame's byte-count */ + __le16 reserved3; +} __attribute__ ((packed)); + +struct iwl4965_rx_mpdu_res_start { + __le16 byte_count; + __le16 reserved; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (5) + * Tx Commands & Responses: + * + * Driver must place each REPLY_TX command into one of the prioritized Tx + * queues in host DRAM, shared between driver and device. When the device's + * Tx scheduler and uCode are preparing to transmit, the device pulls the + * Tx command over the PCI bus via one of the device's Tx DMA channels, + * to fill an internal FIFO from which data will be transmitted. + * + * uCode handles all timing and protocol related to control frames + * (RTS/CTS/ACK), based on flags in the Tx command. + * + * 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). + * + * 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. + *****************************************************************************/ + +/* REPLY_TX Tx flags field */ + +/* 1: Use Request-To-Send protocol before this frame. + * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ +#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) + +/* 1: Transmit Clear-To-Send to self before this frame. + * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. + * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ +#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) + +/* 1: Expect ACK from receiving station + * 0: Don't expect ACK (MAC header's duration field s/b 0) + * Set this for unicast frames, but not broadcast/multicast. */ +#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) + +/* 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. + * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. + * This rate will be used for all Tx attempts; it will not be scaled. */ +#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) + +/* 1: Expect immediate block-ack. + * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ +#define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) + +/* 1: Frame requires full Tx-Op protection. + * Set this if either RTS or CTS Tx Flag gets set. */ +#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) + +/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. + * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ +#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) +#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) +#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) + +/* 1: Ignore Bluetooth priority for this frame. + * 0: Delay Tx until Bluetooth device is done (normal usage). */ +#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) + +/* 1: uCode overrides sequence control field in MAC header. + * 0: Driver provides sequence control field in MAC header. + * Set this for management frames, non-QOS data frames, non-unicast frames, + * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ +#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) + +/* 1: This frame is non-last MPDU; more fragments are coming. + * 0: Last fragment, or not using fragmentation. */ +#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) + +/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. + * 0: No TSF required in outgoing frame. + * Set this for transmitting beacons and probe responses. */ +#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) + +/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword + * alignment of frame's payload data field. + * 0: No pad + * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 + * field (but not both). Driver must align frame data (i.e. data following + * MAC header) to DWORD boundary. */ +#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) + +/* HCCA-AP - disable duration overwriting. */ +#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) + +/* + * TX command security control + */ +#define TX_CMD_SEC_WEP 0x01 +#define TX_CMD_SEC_CCM 0x02 +#define TX_CMD_SEC_TKIP 0x03 +#define TX_CMD_SEC_MSK 0x03 +#define TX_CMD_SEC_SHIFT 6 +#define TX_CMD_SEC_KEY128 0x08 + +/* + * REPLY_TX = 0x1c (command) + */ +struct iwl3945_tx_cmd { + /* + * MPDU byte count: + * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, + * + 8 byte IV for CCM or TKIP (not used for WEP) + * + Data payload + * + 8-byte MIC (not used for CCM/WEP) + * NOTE: Does not include Tx command bytes, post-MAC pad bytes, + * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i + * Range: 14-2342 bytes. + */ + __le16 len; + + /* + * MPDU or MSDU byte count for next frame. + * Used for fragmentation and bursting, but not 11n aggregation. + * Same as "len", but for next frame. Set to 0 if not applicable. + */ + __le16 next_frame_len; + + __le32 tx_flags; /* TX_CMD_FLG_* */ + + u8 rate; + + /* Index of recipient station in uCode's station table */ + u8 sta_id; + u8 tid_tspec; + u8 sec_ctl; + u8 key[16]; + union { + u8 byte[8]; + __le16 word[4]; + __le32 dw[2]; + } tkip_mic; + __le32 next_frame_info; + union { + __le32 life_time; + __le32 attempt; + } stop_time; + u8 supp_rates[2]; + u8 rts_retry_limit; /*byte 50 */ + u8 data_retry_limit; /*byte 51 */ + union { + __le16 pm_frame_timeout; + __le16 attempt_duration; + } timeout; + + /* + * Duration of EDCA burst Tx Opportunity, in 32-usec units. + * Set this if txop time is not specified by HCCA protocol (e.g. by AP). + */ + __le16 driver_txop; + + /* + * MAC header goes here, followed by 2 bytes padding if MAC header + * length is 26 or 30 bytes, followed by payload data + */ + u8 payload[0]; + struct ieee80211_hdr hdr[0]; +} __attribute__ ((packed)); + +/* TX command response is sent after *all* transmission attempts. + * + * NOTES: + * + * TX_STATUS_FAIL_NEXT_FRAG + * + * If the fragment flag in the MAC header for the frame being transmitted + * is set and there is insufficient time to transmit the next frame, the + * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. + * + * TX_STATUS_FIFO_UNDERRUN + * + * Indicates the host did not provide bytes to the FIFO fast enough while + * a TX was in progress. + * + * TX_STATUS_FAIL_MGMNT_ABORT + * + * This status is only possible if the ABORT ON MGMT RX parameter was + * set to true with the TX command. + * + * If the MSB of the status parameter is set then an abort sequence is + * required. This sequence consists of the host activating the TX Abort + * control line, and then waiting for the TX Abort command response. This + * indicates that a the device is no longer in a transmit state, and that the + * command FIFO has been cleared. The host must then deactivate the TX Abort + * control line. Receiving is still allowed in this case. + */ +enum { + TX_STATUS_SUCCESS = 0x01, + TX_STATUS_DIRECT_DONE = 0x02, + TX_STATUS_FAIL_SHORT_LIMIT = 0x82, + TX_STATUS_FAIL_LONG_LIMIT = 0x83, + TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, + TX_STATUS_FAIL_MGMNT_ABORT = 0x85, + TX_STATUS_FAIL_NEXT_FRAG = 0x86, + TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, + TX_STATUS_FAIL_DEST_PS = 0x88, + TX_STATUS_FAIL_ABORTED = 0x89, + TX_STATUS_FAIL_BT_RETRY = 0x8a, + TX_STATUS_FAIL_STA_INVALID = 0x8b, + TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, + TX_STATUS_FAIL_TID_DISABLE = 0x8d, + TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, + TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, + TX_STATUS_FAIL_TX_LOCKED = 0x90, + TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, +}; + +#define TX_PACKET_MODE_REGULAR 0x0000 +#define TX_PACKET_MODE_BURST_SEQ 0x0100 +#define TX_PACKET_MODE_BURST_FIRST 0x0200 + +enum { + TX_POWER_PA_NOT_ACTIVE = 0x0, +}; + +enum { + TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ + TX_STATUS_DELAY_MSK = 0x00000040, + TX_STATUS_ABORT_MSK = 0x00000080, + TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ + TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ + TX_RESERVED = 0x00780000, /* bits 19:22 */ + TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ + TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ +}; + +/* + * REPLY_TX = 0x1c (response) + */ +struct iwl3945_tx_resp { + u8 failure_rts; + u8 failure_frame; + u8 bt_kill_count; + u8 rate; + __le32 wireless_media_time; + __le32 status; /* TX status */ +} __attribute__ ((packed)); + +/* + * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) + */ +struct iwl3945_txpowertable_cmd { + u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ + u8 reserved; + __le16 channel; + struct iwl3945_power_per_rate power[IWL_MAX_RATES]; +} __attribute__ ((packed)); + +struct iwl3945_rate_scaling_info { + __le16 rate_n_flags; + u8 try_cnt; + u8 next_rate_index; +} __attribute__ ((packed)); + +/** + * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response + * + * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) + * + * NOTE: The table of rates passed to the uCode via the + * RATE_SCALE command sets up the corresponding order of + * rates used for all related commands, including rate + * masks, etc. + * + * For example, if you set 9MB (PLCP 0x0f) as the first + * rate in the rate table, the bit mask for that rate + * when passed through ofdm_basic_rates on the REPLY_RXON + * command would be bit 0 (1<<0) + */ +struct iwl3945_rate_scaling_cmd { + u8 table_id; + u8 reserved[3]; + struct iwl3945_rate_scaling_info table[IWL_MAX_RATES]; +} __attribute__ ((packed)); + +/* + * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) + */ +struct iwl3945_bt_cmd { + u8 flags; + u8 lead_time; + u8 max_kill; + u8 reserved; + __le32 kill_ack_mask; + __le32 kill_cts_mask; +} __attribute__ ((packed)); + +/****************************************************************************** + * (6) + * Spectrum Management (802.11h) Commands, Responses, Notifications: + * + *****************************************************************************/ + +/* + * Spectrum Management + */ +#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ + RXON_FILTER_CTL2HOST_MSK | \ + RXON_FILTER_ACCEPT_GRP_MSK | \ + RXON_FILTER_DIS_DECRYPT_MSK | \ + RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ + RXON_FILTER_ASSOC_MSK | \ + RXON_FILTER_BCON_AWARE_MSK) + +struct iwl3945_measure_channel { + __le32 duration; /* measurement duration in extended beacon + * format */ + u8 channel; /* channel to measure */ + u8 type; /* see enum iwl3945_measure_type */ + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) + */ +struct iwl3945_spectrum_cmd { + __le16 len; /* number of bytes starting from token */ + u8 token; /* token id */ + u8 id; /* measurement id -- 0 or 1 */ + u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ + u8 periodic; /* 1 = periodic */ + __le16 path_loss_timeout; + __le32 start_time; /* start time in extended beacon format */ + __le32 reserved2; + __le32 flags; /* rxon flags */ + __le32 filter_flags; /* rxon filter flags */ + __le16 channel_count; /* minimum 1, maximum 10 */ + __le16 reserved3; + struct iwl3945_measure_channel channels[10]; +} __attribute__ ((packed)); + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) + */ +struct iwl3945_spectrum_resp { + u8 token; + u8 id; /* id of the prior command replaced, or 0xff */ + __le16 status; /* 0 - command will be handled + * 1 - cannot handle (conflicts with another + * measurement) */ +} __attribute__ ((packed)); + +enum iwl3945_measurement_state { + IWL_MEASUREMENT_START = 0, + IWL_MEASUREMENT_STOP = 1, +}; + +enum iwl3945_measurement_status { + IWL_MEASUREMENT_OK = 0, + IWL_MEASUREMENT_CONCURRENT = 1, + IWL_MEASUREMENT_CSA_CONFLICT = 2, + IWL_MEASUREMENT_TGH_CONFLICT = 3, + /* 4-5 reserved */ + IWL_MEASUREMENT_STOPPED = 6, + IWL_MEASUREMENT_TIMEOUT = 7, + IWL_MEASUREMENT_PERIODIC_FAILED = 8, +}; + +#define NUM_ELEMENTS_IN_HISTOGRAM 8 + +struct iwl3945_measurement_histogram { + __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ + __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ +} __attribute__ ((packed)); + +/* clear channel availability counters */ +struct iwl3945_measurement_cca_counters { + __le32 ofdm; + __le32 cck; +} __attribute__ ((packed)); + +enum iwl3945_measure_type { + IWL_MEASURE_BASIC = (1 << 0), + IWL_MEASURE_CHANNEL_LOAD = (1 << 1), + IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), + IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), + IWL_MEASURE_FRAME = (1 << 4), + /* bits 5:6 are reserved */ + IWL_MEASURE_IDLE = (1 << 7), +}; + +/* + * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) + */ +struct iwl3945_spectrum_notification { + u8 id; /* measurement id -- 0 or 1 */ + u8 token; + u8 channel_index; /* index in measurement channel list */ + u8 state; /* 0 - start, 1 - stop */ + __le32 start_time; /* lower 32-bits of TSF */ + u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ + u8 channel; + u8 type; /* see enum iwl3945_measurement_type */ + u8 reserved1; + /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only + * valid if applicable for measurement type requested. */ + __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ + __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ + __le32 cca_time; /* channel load time in usecs */ + u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - + * unidentified */ + u8 reserved2[3]; + struct iwl3945_measurement_histogram histogram; + __le32 stop_time; /* lower 32-bits of TSF */ + __le32 status; /* see iwl3945_measurement_status */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (7) + * Power Management Commands, Responses, Notifications: + * + *****************************************************************************/ + +/** + * struct iwl3945_powertable_cmd - Power Table Command + * @flags: See below: + * + * POWER_TABLE_CMD = 0x77 (command, has simple generic response) + * + * PM allow: + * bit 0 - '0' Driver not allow power management + * '1' Driver allow PM (use rest of parameters) + * uCode send sleep notifications: + * bit 1 - '0' Don't send sleep notification + * '1' send sleep notification (SEND_PM_NOTIFICATION) + * Sleep over DTIM + * bit 2 - '0' PM have to walk up every DTIM + * '1' PM could sleep over DTIM till listen Interval. + * PCI power managed + * bit 3 - '0' (PCI_LINK_CTRL & 0x1) + * '1' !(PCI_LINK_CTRL & 0x1) + * Force sleep Modes + * bit 31/30- '00' use both mac/xtal sleeps + * '01' force Mac sleep + * '10' force xtal sleep + * '11' Illegal set + * + * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then + * ucode assume sleep over DTIM is allowed and we don't need to wakeup + * for every DTIM. + */ +#define IWL_POWER_VEC_SIZE 5 + +#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le32(1<<0) +#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le32(1<<2) +#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le32(1<<3) +struct iwl3945_powertable_cmd { + __le32 flags; + __le32 rx_data_timeout; + __le32 tx_data_timeout; + __le32 sleep_interval[IWL_POWER_VEC_SIZE]; +} __attribute__((packed)); + +/* + * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) + * 3945 and 4965 identical. + */ +struct iwl3945_sleep_notification { + u8 pm_sleep_mode; + u8 pm_wakeup_src; + __le16 reserved; + __le32 sleep_time; + __le32 tsf_low; + __le32 bcon_timer; +} __attribute__ ((packed)); + +/* Sleep states. 3945 and 4965 identical. */ +enum { + IWL_PM_NO_SLEEP = 0, + IWL_PM_SLP_MAC = 1, + IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, + IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, + IWL_PM_SLP_PHY = 4, + IWL_PM_SLP_REPENT = 5, + IWL_PM_WAKEUP_BY_TIMER = 6, + IWL_PM_WAKEUP_BY_DRIVER = 7, + IWL_PM_WAKEUP_BY_RFKILL = 8, + /* 3 reserved */ + IWL_PM_NUM_OF_MODES = 12, +}; + +/* + * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) + */ +#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ +#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ +#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ +struct iwl3945_card_state_cmd { + __le32 status; /* CARD_STATE_CMD_* request new power state */ +} __attribute__ ((packed)); + +/* + * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) + */ +struct iwl3945_card_state_notif { + __le32 flags; +} __attribute__ ((packed)); + +#define HW_CARD_DISABLED 0x01 +#define SW_CARD_DISABLED 0x02 +#define RF_CARD_DISABLED 0x04 +#define RXON_CARD_DISABLED 0x10 + +struct iwl3945_ct_kill_config { + __le32 reserved; + __le32 critical_temperature_M; + __le32 critical_temperature_R; +} __attribute__ ((packed)); + +/****************************************************************************** + * (8) + * Scan Commands, Responses, Notifications: + * + *****************************************************************************/ + +struct iwl3945_scan_channel { + /* type is defined as: + * 0:0 active (0 - passive) + * 1:4 SSID direct + * If 1 is set then corresponding SSID IE is transmitted in probe + * 5:7 reserved + */ + u8 type; + u8 channel; + struct iwl3945_tx_power tpc; + __le16 active_dwell; + __le16 passive_dwell; +} __attribute__ ((packed)); + +struct iwl3945_ssid_ie { + u8 id; + u8 len; + u8 ssid[32]; +} __attribute__ ((packed)); + +#define PROBE_OPTION_MAX 0x4 +#define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) +#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) +#define IWL_MAX_SCAN_SIZE 1024 + +/* + * REPLY_SCAN_CMD = 0x80 (command) + */ +struct iwl3945_scan_cmd { + __le16 len; + u8 reserved0; + u8 channel_count; + __le16 quiet_time; /* dwell only this long on quiet chnl + * (active scan) */ + __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ + __le16 good_CRC_th; /* passive -> active promotion threshold */ + __le16 reserved1; + __le32 max_out_time; /* max usec to be out of associated (service) + * chnl */ + __le32 suspend_time; /* pause scan this long when returning to svc + * chnl. + * 3945 -- 31:24 # beacons, 19:0 additional usec, + * 4965 -- 31:22 # beacons, 21:0 additional usec. + */ + __le32 flags; + __le32 filter_flags; + + struct iwl3945_tx_cmd tx_cmd; + struct iwl3945_ssid_ie direct_scan[PROBE_OPTION_MAX]; + + u8 data[0]; + /* + * The channels start after the probe request payload and are of type: + * + * struct iwl3945_scan_channel channels[0]; + * + * NOTE: Only one band of channels can be scanned per pass. You + * can not mix 2.4GHz channels and 5.2GHz channels and must + * request a scan multiple times (not concurrently) + * + */ +} __attribute__ ((packed)); + +/* Can abort will notify by complete notification with abort status. */ +#define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) +/* complete notification statuses */ +#define ABORT_STATUS 0x2 + +/* + * REPLY_SCAN_CMD = 0x80 (response) + */ +struct iwl3945_scanreq_notification { + __le32 status; /* 1: okay, 2: cannot fulfill request */ +} __attribute__ ((packed)); + +/* + * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) + */ +struct iwl3945_scanstart_notification { + __le32 tsf_low; + __le32 tsf_high; + __le32 beacon_timer; + u8 channel; + u8 band; + u8 reserved[2]; + __le32 status; +} __attribute__ ((packed)); + +#define SCAN_OWNER_STATUS 0x1; +#define MEASURE_OWNER_STATUS 0x2; + +#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ +/* + * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) + */ +struct iwl3945_scanresults_notification { + u8 channel; + u8 band; + u8 reserved[2]; + __le32 tsf_low; + __le32 tsf_high; + __le32 statistics[NUMBER_OF_STATISTICS]; +} __attribute__ ((packed)); + +/* + * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) + */ +struct iwl3945_scancomplete_notification { + u8 scanned_channels; + u8 status; + u8 reserved; + u8 last_channel; + __le32 tsf_low; + __le32 tsf_high; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (9) + * IBSS/AP Commands and Notifications: + * + *****************************************************************************/ + +/* + * BEACON_NOTIFICATION = 0x90 (notification only, not a command) + */ +struct iwl3945_beacon_notif { + struct iwl3945_tx_resp beacon_notify_hdr; + __le32 low_tsf; + __le32 high_tsf; + __le32 ibss_mgr_status; +} __attribute__ ((packed)); + +/* + * REPLY_TX_BEACON = 0x91 (command, has simple generic response) + */ +struct iwl3945_tx_beacon_cmd { + struct iwl3945_tx_cmd tx; + __le16 tim_idx; + u8 tim_size; + u8 reserved1; + struct ieee80211_hdr frame[0]; /* beacon frame */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (10) + * Statistics Commands and Notifications: + * + *****************************************************************************/ + +#define IWL_TEMP_CONVERT 260 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/* Used for passing to driver number of successes and failures per rate */ +struct rate_histogram { + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } success; + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } failed; +} __attribute__ ((packed)); + +/* statistics command response */ + +struct statistics_rx_phy { + __le32 ina_cnt; + __le32 fina_cnt; + __le32 plcp_err; + __le32 crc32_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 false_alarm_cnt; + __le32 fina_sync_err_cnt; + __le32 sfd_timeout; + __le32 fina_timeout; + __le32 unresponded_rts; + __le32 rxe_frame_limit_overrun; + __le32 sent_ack_cnt; + __le32 sent_cts_cnt; +} __attribute__ ((packed)); + +struct statistics_rx_non_phy { + __le32 bogus_cts; /* CTS received when not expecting CTS */ + __le32 bogus_ack; /* ACK received when not expecting ACK */ + __le32 non_bssid_frames; /* number of frames with BSSID that + * doesn't belong to the STA BSSID */ + __le32 filtered_frames; /* count frames that were dumped in the + * filtering process */ + __le32 non_channel_beacons; /* beacons with our bss id but not on + * our serving channel */ +} __attribute__ ((packed)); + +struct statistics_rx { + struct statistics_rx_phy ofdm; + struct statistics_rx_phy cck; + struct statistics_rx_non_phy general; +} __attribute__ ((packed)); + +struct statistics_tx { + __le32 preamble_cnt; + __le32 rx_detected_cnt; + __le32 bt_prio_defer_cnt; + __le32 bt_prio_kill_cnt; + __le32 few_bytes_cnt; + __le32 cts_timeout; + __le32 ack_timeout; + __le32 expected_ack_cnt; + __le32 actual_ack_cnt; +} __attribute__ ((packed)); + +struct statistics_dbg { + __le32 burst_check; + __le32 burst_count; + __le32 reserved[4]; +} __attribute__ ((packed)); + +struct statistics_div { + __le32 tx_on_a; + __le32 tx_on_b; + __le32 exec_time; + __le32 probe_time; +} __attribute__ ((packed)); + +struct statistics_general { + __le32 temperature; + struct statistics_dbg dbg; + __le32 sleep_time; + __le32 slots_out; + __le32 slots_idle; + __le32 ttl_timestamp; + struct statistics_div div; +} __attribute__ ((packed)); + +/* + * REPLY_STATISTICS_CMD = 0x9c, + * 3945 and 4965 identical. + * + * This command triggers an immediate response containing uCode statistics. + * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. + * + * If the CLEAR_STATS configuration flag is set, uCode will clear its + * internal copy of the statistics (counters) after issuing the response. + * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). + * + * If the DISABLE_NOTIF configuration flag is set, uCode will not issue + * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag + * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. + */ +#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ +#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ +struct iwl3945_statistics_cmd { + __le32 configuration_flags; /* IWL_STATS_CONF_* */ +} __attribute__ ((packed)); + +/* + * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) + * + * By default, uCode issues this notification after receiving a beacon + * while associated. To disable this behavior, set DISABLE_NOTIF flag in the + * REPLY_STATISTICS_CMD 0x9c, above. + * + * Statistics counters continue to increment beacon after beacon, but are + * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD + * 0x9c with CLEAR_STATS bit set (see above). + * + * uCode also issues this notification during scans. uCode clears statistics + * appropriately so that each notification contains statistics for only the + * one channel that has just been scanned. + */ +#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) +#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) +struct iwl3945_notif_statistics { + __le32 flag; + struct statistics_rx rx; + struct statistics_tx tx; + struct statistics_general general; +} __attribute__ ((packed)); + + +/* + * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) + */ +/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, + * then this notification will be sent. */ +#define CONSECUTIVE_MISSED_BCONS_TH 20 + +struct iwl3945_missed_beacon_notif { + __le32 consequtive_missed_beacons; + __le32 total_missed_becons; + __le32 num_expected_beacons; + __le32 num_recvd_beacons; +} __attribute__ ((packed)); + +/****************************************************************************** + * (11) + * Rx Calibration Commands: + * + *****************************************************************************/ + +#define PHY_CALIBRATE_DIFF_GAIN_CMD (7) +#define HD_TABLE_SIZE (11) + +struct iwl3945_sensitivity_cmd { + __le16 control; + __le16 table[HD_TABLE_SIZE]; +} __attribute__ ((packed)); + +struct iwl3945_calibration_cmd { + u8 opCode; + u8 flags; + __le16 reserved; + s8 diff_gain_a; + s8 diff_gain_b; + s8 diff_gain_c; + u8 reserved1; +} __attribute__ ((packed)); + +/****************************************************************************** + * (12) + * Miscellaneous Commands: + * + *****************************************************************************/ + +/* + * LEDs Command & Response + * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) + * + * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), + * this command turns it on or off, or sets up a periodic blinking cycle. + */ +struct iwl3945_led_cmd { + __le32 interval; /* "interval" in uSec */ + u8 id; /* 1: Activity, 2: Link, 3: Tech */ + u8 off; /* # intervals off while blinking; + * "0", with >0 "on" value, turns LED on */ + u8 on; /* # intervals on while blinking; + * "0", regardless of "off", turns LED off */ + u8 reserved; +} __attribute__ ((packed)); + +/****************************************************************************** + * (13) + * Union of all expected notifications/responses: + * + *****************************************************************************/ + +struct iwl3945_rx_packet { + __le32 len; + struct iwl3945_cmd_header hdr; + union { + struct iwl3945_alive_resp alive_frame; + struct iwl3945_rx_frame rx_frame; + struct iwl3945_tx_resp tx_resp; + struct iwl3945_spectrum_notification spectrum_notif; + struct iwl3945_csa_notification csa_notif; + struct iwl3945_error_resp err_resp; + struct iwl3945_card_state_notif card_state_notif; + struct iwl3945_beacon_notif beacon_status; + struct iwl3945_add_sta_resp add_sta; + struct iwl3945_sleep_notification sleep_notif; + struct iwl3945_spectrum_resp spectrum; + struct iwl3945_notif_statistics stats; + __le32 status; + u8 raw[0]; + } u; +} __attribute__ ((packed)); + +#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl3945_rx_frame)) + +#endif /* __iwl3945_3945_commands_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-debug.h b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h new file mode 100644 index 0000000..ebf0168 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-debug.h @@ -0,0 +1,152 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl3945_debug_h__ +#define __iwl3945_debug_h__ + +#ifdef CONFIG_IWL3945_DEBUG +extern u32 iwl3945_debug_level; +#define IWL_DEBUG(level, fmt, args...) \ +do { if (iwl3945_debug_level & (level)) \ + printk(KERN_ERR DRV_NAME": %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) + +#define IWL_DEBUG_LIMIT(level, fmt, args...) \ +do { if ((iwl3945_debug_level & (level)) && net_ratelimit()) \ + printk(KERN_ERR DRV_NAME": %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) +#else +static inline void IWL_DEBUG(int level, const char *fmt, ...) +{ +} +static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) +{ +} +#endif /* CONFIG_IWL3945_DEBUG */ + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define IWL_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a IWL_xxxx_DEBUG() macro definition for your + * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/iwl/debug_level + * + * you simply need to add your entry to the iwl3945_debug_levels array. + * + * If you do not see debug_level in /proc/net/iwl then you do not have + * CONFIG_IWL3945_DEBUG defined in your kernel configuration + * + */ + +#define IWL_DL_INFO (1<<0) +#define IWL_DL_MAC80211 (1<<1) +#define IWL_DL_HOST_COMMAND (1<<2) +#define IWL_DL_STATE (1<<3) + +#define IWL_DL_RADIO (1<<7) +#define IWL_DL_POWER (1<<8) +#define IWL_DL_TEMP (1<<9) + +#define IWL_DL_NOTIF (1<<10) +#define IWL_DL_SCAN (1<<11) +#define IWL_DL_ASSOC (1<<12) +#define IWL_DL_DROP (1<<13) + +#define IWL_DL_TXPOWER (1<<14) + +#define IWL_DL_AP (1<<15) + +#define IWL_DL_FW (1<<16) +#define IWL_DL_RF_KILL (1<<17) +#define IWL_DL_FW_ERRORS (1<<18) + +#define IWL_DL_LED (1<<19) + +#define IWL_DL_RATE (1<<20) + +#define IWL_DL_CALIB (1<<21) +#define IWL_DL_WEP (1<<22) +#define IWL_DL_TX (1<<23) +#define IWL_DL_RX (1<<24) +#define IWL_DL_ISR (1<<25) +#define IWL_DL_HT (1<<26) +#define IWL_DL_IO (1<<27) +#define IWL_DL_11H (1<<28) + +#define IWL_DL_STATS (1<<29) +#define IWL_DL_TX_REPLY (1<<30) +#define IWL_DL_QOS (1<<31) + +#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) +#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) +#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) + +#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) +#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) +#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) +#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) +#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) +#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) +#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) +#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) +#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a) +#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) +#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) +#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) +#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) +#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) +#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) +#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) +#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ + IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) +#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) +#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) +#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) +#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) +#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) +#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) + +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index fb5f064..2c955a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -8,7 +8,7 @@ * Copyright(c) 2005 - 2007 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 Geeral Public License as + * 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 @@ -60,58 +60,646 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* + * 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-3945.h for driver implementation definitions. + */ #ifndef __iwl_3945_hw__ #define __iwl_3945_hw__ -#define IWL_RX_BUF_SIZE 3000 -/* card static random access memory (SRAM) for processor data and instructs */ +/* + * uCode queue management definitions ... + * Queue #4 is the command queue for 3945 and 4965. + */ +#define IWL_CMD_QUEUE_NUM 4 + +/* Tx rates */ +#define IWL_CCK_RATES 4 +#define IWL_OFDM_RATES 8 +#define IWL_HT_RATES 0 +#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES) + +/* Time constants */ +#define SHORT_SLOT_TIME 9 +#define LONG_SLOT_TIME 20 + +/* RSSI to dBm */ +#define IWL_RSSI_OFFSET 95 + +/* + * EEPROM related constants, enums, and structures. + */ + +/* + * EEPROM access time values: + * + * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG, + * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit + * CSR_EEPROM_REG_BIT_CMD (0x2). + * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). + * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. + * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. + */ +#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ +#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */ + +/* + * Regulatory channel usage flags in EEPROM struct iwl_eeprom_channel.flags. + * + * IBSS and/or AP operation is allowed *only* on those channels with + * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because + * RADAR detection is not supported by the 3945 driver, but is a + * requirement for establishing a new network for legal operation on channels + * requiring RADAR detection or restricting ACTIVE scanning. + * + * NOTE: "WIDE" flag indicates that 20 MHz channel is supported; + * 3945 does not support FAT 40 MHz-wide channels. + * + * NOTE: Using a channel inappropriately will result in a uCode error! + */ +enum { + EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ + EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ + /* Bit 2 Reserved */ + EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ + EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ + EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ + EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */ + EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ +}; + +/* SKU Capabilities */ +#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) +#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) +#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) + +/* *regulatory* channel data from eeprom, one for each channel */ +struct iwl3945_eeprom_channel { + u8 flags; /* flags copied from EEPROM */ + s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ +} __attribute__ ((packed)); + +/* + * Mapping of a Tx power level, at factory calibration temperature, + * to a radio/DSP gain table index. + * One for each of 5 "sample" power levels in each band. + * v_det is measured at the factory, using the 3945's built-in power amplifier + * (PA) output voltage detector. This same detector is used during Tx of + * long packets in normal operation to provide feedback as to proper output + * level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_sample { + u8 gain_index; /* index into power (gain) setup table ... */ + s8 power; /* ... for this pwr level for this chnl group */ + u16 v_det; /* PA output voltage */ +} __attribute__ ((packed)); + +/* + * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. + * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). + * Tx power setup code interpolates between the 5 "sample" power levels + * to determine the nominal setup for a requested power level. + * Data copied from EEPROM. + * DO NOT ALTER THIS STRUCTURE!!! + */ +struct iwl3945_eeprom_txpower_group { + struct iwl3945_eeprom_txpower_sample samples[5]; /* 5 power levels */ + s32 a, b, c, d, e; /* coefficients for voltage->power + * formula (signed) */ + s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on + * frequency (signed) */ + s8 saturation_power; /* highest power possible by h/w in this + * band */ + u8 group_channel; /* "representative" channel # in this band */ + s16 temperature; /* h/w temperature at factory calib this band + * (signed) */ +} __attribute__ ((packed)); + +/* + * Temperature-based Tx-power compensation data, not band-specific. + * These coefficients are use to modify a/b/c/d/e coeffs based on + * difference between current temperature and factory calib temperature. + * Data copied from EEPROM. + */ +struct iwl3945_eeprom_temperature_corr { + u32 Ta; + u32 Tb; + u32 Tc; + u32 Td; + u32 Te; +} __attribute__ ((packed)); + +/* + * EEPROM map + */ +struct iwl3945_eeprom { + u8 reserved0[16]; +#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ + u16 device_id; /* abs.ofs: 16 */ + u8 reserved1[2]; +#define EEPROM_PMC (2*0x0A) /* 2 bytes */ + u16 pmc; /* abs.ofs: 20 */ + u8 reserved2[20]; +#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ + u8 mac_address[6]; /* abs.ofs: 42 */ + u8 reserved3[58]; +#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ + u16 board_revision; /* abs.ofs: 106 */ + u8 reserved4[11]; +#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ + u8 board_pba_number[9]; /* abs.ofs: 119 */ + u8 reserved5[8]; +#define EEPROM_VERSION (2*0x44) /* 2 bytes */ + u16 version; /* abs.ofs: 136 */ +#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ + u8 sku_cap; /* abs.ofs: 138 */ +#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */ + u8 leds_mode; /* abs.ofs: 139 */ +#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ + u16 oem_mode; +#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ + u16 wowlan_mode; /* abs.ofs: 142 */ +#define EEPROM_LEDS_TIME_INTERVAL (2*0x48) /* 2 bytes */ + u16 leds_time_interval; /* abs.ofs: 144 */ +#define EEPROM_LEDS_OFF_TIME (2*0x49) /* 1 bytes */ + u8 leds_off_time; /* abs.ofs: 146 */ +#define EEPROM_LEDS_ON_TIME (2*0x49+1) /* 1 bytes */ + u8 leds_on_time; /* abs.ofs: 147 */ +#define EEPROM_ALMGOR_M_VERSION (2*0x4A) /* 1 bytes */ + u8 almgor_m_version; /* abs.ofs: 148 */ +#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */ + u8 antenna_switch_type; /* abs.ofs: 149 */ + u8 reserved6[42]; +#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */ + u8 sku_id[4]; /* abs.ofs: 192 */ + +/* + * Per-channel regulatory data. + * + * Each channel that *might* be supported by 3945 or 4965 has a fixed location + * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory + * txpower (MSB). + * + * Entries immediately below are for 20 MHz channel width. FAT (40 MHz) + * channels (only for 4965, not supported by 3945) appear later in the EEPROM. + * + * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ +#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */ + u16 band_1_count; /* abs.ofs: 196 */ +#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */ + struct iwl3945_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */ + +/* + * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, + * 5.0 GHz channels 7, 8, 11, 12, 16 + * (4915-5080MHz) (none of these is ever supported) + */ +#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */ + u16 band_2_count; /* abs.ofs: 226 */ +#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */ + struct iwl3945_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ + +/* + * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 + * (5170-5320MHz) + */ +#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */ + u16 band_3_count; /* abs.ofs: 254 */ +#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */ + struct iwl3945_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ + +/* + * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 + * (5500-5700MHz) + */ +#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */ + u16 band_4_count; /* abs.ofs: 280 */ +#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */ + struct iwl3945_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ + +/* + * 5.7 GHz channels 145, 149, 153, 157, 161, 165 + * (5725-5825MHz) + */ +#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */ + u16 band_5_count; /* abs.ofs: 304 */ +#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */ + struct iwl3945_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ + + u8 reserved9[194]; + +/* + * 3945 Txpower calibration data. + */ +#define EEPROM_TXPOWER_CALIB_GROUP0 0x200 +#define EEPROM_TXPOWER_CALIB_GROUP1 0x240 +#define EEPROM_TXPOWER_CALIB_GROUP2 0x280 +#define EEPROM_TXPOWER_CALIB_GROUP3 0x2c0 +#define EEPROM_TXPOWER_CALIB_GROUP4 0x300 +#define IWL_NUM_TX_CALIB_GROUPS 5 + struct iwl3945_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; +/* abs.ofs: 512 */ +#define EEPROM_CALIB_TEMPERATURE_CORRECT 0x340 + struct iwl3945_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ + u8 reserved16[172]; /* fill out to full 1024 byte block */ +} __attribute__ ((packed)); + +#define IWL_EEPROM_IMAGE_SIZE 1024 + +/* End of EEPROM */ + + +#include "iwl-3945-commands.h" + +#define PCI_LINK_CTRL 0x0F0 +#define PCI_POWER_SOURCE 0x0C8 +#define PCI_REG_WUM8 0x0E8 +#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) + +/*=== CSR (control and status registers) ===*/ +#define CSR_BASE (0x000) + +#define CSR_SW_VER (CSR_BASE+0x000) +#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ +#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ +#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ +#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ +#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ +#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */ +#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ +#define CSR_GP_CNTRL (CSR_BASE+0x024) + +/* + * Hardware revision info + * Bit fields: + * 31-8: Reserved + * 7-4: Type of device: 0x0 = 4965, 0xd = 3945 + * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D + * 1-0: "Dash" value, as in A-1, etc. + */ +#define CSR_HW_REV (CSR_BASE+0x028) + +/* EEPROM reads */ +#define CSR_EEPROM_REG (CSR_BASE+0x02c) +#define CSR_EEPROM_GP (CSR_BASE+0x030) +#define CSR_GP_UCODE (CSR_BASE+0x044) +#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) +#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) +#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) +#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) +#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) + +/* Analog phase-lock-loop configuration (3945 only) + * Set bit 24. */ +#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) + +/* Bits for CSR_HW_IF_CONFIG_REG */ +#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB (0x00000100) +#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM (0x00000200) +#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) +#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) +#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) +#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) +#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) + +/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), + * acknowledged (reset) by host writing "1" to flagged bits. */ +#define CSR_INT_BIT_FH_RX (1<<31) /* Rx DMA, cmd responses, FH_INT[17:16] */ +#define CSR_INT_BIT_HW_ERR (1<<29) /* DMA hardware error FH_INT[31] */ +#define CSR_INT_BIT_DNLD (1<<28) /* uCode Download */ +#define CSR_INT_BIT_FH_TX (1<<27) /* Tx DMA FH_INT[1:0] */ +#define CSR_INT_BIT_MAC_CLK_ACTV (1<<26) /* NIC controller's clock toggled on/off */ +#define CSR_INT_BIT_SW_ERR (1<<25) /* uCode error */ +#define CSR_INT_BIT_RF_KILL (1<<7) /* HW RFKILL switch GP_CNTRL[27] toggled */ +#define CSR_INT_BIT_CT_KILL (1<<6) /* Critical temp (chip too hot) rfkill */ +#define CSR_INT_BIT_SW_RX (1<<3) /* Rx, command responses, 3945 */ +#define CSR_INT_BIT_WAKEUP (1<<1) /* NIC controller waking up (pwr mgmt) */ +#define CSR_INT_BIT_ALIVE (1<<0) /* uCode interrupts once it initializes */ + +#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ + CSR_INT_BIT_HW_ERR | \ + CSR_INT_BIT_FH_TX | \ + CSR_INT_BIT_SW_ERR | \ + CSR_INT_BIT_RF_KILL | \ + CSR_INT_BIT_SW_RX | \ + CSR_INT_BIT_WAKEUP | \ + CSR_INT_BIT_ALIVE) + +/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ +#define CSR_FH_INT_BIT_ERR (1<<31) /* Error */ +#define CSR_FH_INT_BIT_HI_PRIOR (1<<30) /* High priority Rx, bypass coalescing */ +#define CSR_FH_INT_BIT_RX_CHNL2 (1<<18) /* Rx channel 2 (3945 only) */ +#define CSR_FH_INT_BIT_RX_CHNL1 (1<<17) /* Rx channel 1 */ +#define CSR_FH_INT_BIT_RX_CHNL0 (1<<16) /* Rx channel 0 */ +#define CSR_FH_INT_BIT_TX_CHNL6 (1<<6) /* Tx channel 6 (3945 only) */ +#define CSR_FH_INT_BIT_TX_CHNL1 (1<<1) /* Tx channel 1 */ +#define CSR_FH_INT_BIT_TX_CHNL0 (1<<0) /* Tx channel 0 */ + +#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR_FH_INT_BIT_RX_CHNL2 | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) + +#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL6 | \ + CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) + + +/* RESET */ +#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001) +#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002) +#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) +#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) +#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) + +/* GP (general purpose) CONTROL */ +#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) +#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) +#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) +#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) + +#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001) + +#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000) +#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000) +#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) + + +/* EEPROM REG */ +#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) +#define CSR_EEPROM_REG_BIT_CMD (0x00000002) + +/* EEPROM GP */ +#define CSR_EEPROM_GP_VALID_MSK (0x00000006) +#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000) +#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) + +/* UCODE DRV GP */ +#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) +#define CSR_UCODE_SW_BIT_RFKILL (0x00000002) +#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) +#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) + +/* GPIO */ +#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) +#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000) +#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER + +/* GI Chicken Bits */ +#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) +#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) + +/* CSR_ANA_PLL_CFG */ +#define CSR_ANA_PLL_CFG_SH (0x00880300) + +/*=== HBUS (Host-side Bus) ===*/ +#define HBUS_BASE (0x400) + +/* + * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM + * structures, error log, event log, verifying uCode load). + * First write to address register, then read from or write to data register + * to complete the job. Once the address register is set up, accesses to + * data registers auto-increment the address by one dword. + * Bit usage for address registers (read or write): + * 0-31: memory address within device + */ +#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c) +#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010) +#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) +#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) + +/* + * Registers for accessing device's internal peripheral registers + * (e.g. SCD, BSM, etc.). First write to address register, + * then read from or write to data register to complete the job. + * Bit usage for address registers (read or write): + * 0-15: register address (offset) within device + * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword) + */ +#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044) +#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048) +#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) +#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) + +/* + * Per-Tx-queue write pointer (index, really!) (3945 and 4965). + * Indicates index to next TFD that driver will fill (1 past latest filled). + * Bit usage: + * 0-7: queue write index + * 11-8: queue selector + */ +#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) + +/* SCD (3945 Tx Frame Scheduler) */ +#define SCD_BASE (CSR_BASE + 0x2E00) + +#define SCD_MODE_REG (SCD_BASE + 0x000) +#define SCD_ARASTAT_REG (SCD_BASE + 0x004) +#define SCD_TXFACT_REG (SCD_BASE + 0x010) +#define SCD_TXF4MF_REG (SCD_BASE + 0x014) +#define SCD_TXF5MF_REG (SCD_BASE + 0x020) +#define SCD_SBYP_MODE_1_REG (SCD_BASE + 0x02C) +#define SCD_SBYP_MODE_2_REG (SCD_BASE + 0x030) + +/*=== FH (data Flow Handler) ===*/ +#define FH_BASE (0x800) + +#define FH_CBCC_TABLE (FH_BASE+0x140) +#define FH_TFDB_TABLE (FH_BASE+0x180) +#define FH_RCSR_TABLE (FH_BASE+0x400) +#define FH_RSSR_TABLE (FH_BASE+0x4c0) +#define FH_TCSR_TABLE (FH_BASE+0x500) +#define FH_TSSR_TABLE (FH_BASE+0x680) + +/* TFDB (Transmit Frame Buffer Descriptor) */ +#define FH_TFDB(_channel, buf) \ + (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28) +#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \ + (FH_TFDB_TABLE + 0x50 * _channel) +/* CBCC _channel is [0,2] */ +#define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8) +#define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00) +#define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04) + +/* RCSR _channel is [0,2] */ +#define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40) +#define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00) +#define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04) +#define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20) +#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24) + +#define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0)) + +/* RSSR */ +#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000) +#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004) +/* TCSR */ +#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20) +#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00) +#define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04) +#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08) +/* TSSR */ +#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000) +#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008) +#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010) + + +/* DBM */ + +#define ALM_FH_SRVC_CHNL (6) + +#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) +#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) + +#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) + +#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) + +#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) + +#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) + +#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) + +#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) + +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) + +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) + +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) + +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) + +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) +#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) + +#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) + +#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) + +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) + +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) + +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) + +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) +#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) + +#define ALM_TB_MAX_BYTES_COUNT (0xFFF0) + +#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \ + ((1LU << _channel) << 24) +#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \ + ((1LU << _channel) << 16) + +#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \ + (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \ + ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel)) +#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ +#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ + +#define TFD_QUEUE_MIN 0 +#define TFD_QUEUE_MAX 6 +#define TFD_QUEUE_SIZE_MAX (256) + +#define IWL_NUM_SCAN_RATES (2) + +#define IWL_DEFAULT_TX_RETRY 15 + +/*********************************************/ + +#define RFD_SIZE 4 +#define NUM_TFD_CHUNKS 4 + +#define RX_QUEUE_SIZE 256 +#define RX_QUEUE_MASK 255 +#define RX_QUEUE_SIZE_LOG 8 + +#define U32_PAD(n) ((4-(n))&0x3) + +#define TFD_CTL_COUNT_SET(n) (n<<24) +#define TFD_CTL_COUNT_GET(ctl) ((ctl>>24) & 7) +#define TFD_CTL_PAD_SET(n) (n<<28) +#define TFD_CTL_PAD_GET(ctl) (ctl>>28) + +#define TFD_TX_CMD_SLOTS 256 +#define TFD_CMD_SLOTS 32 + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \ + sizeof(struct iwl3945_cmd_meta)) + +/* + * RX related structures and functions + */ +#define RX_FREE_BUFFERS 64 +#define RX_LOW_WATERMARK 8 + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 3945's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define RTC_INST_LOWER_BOUND (0x000000) #define ALM_RTC_INST_UPPER_BOUND (0x014000) + +#define RTC_DATA_LOWER_BOUND (0x800000) #define ALM_RTC_DATA_UPPER_BOUND (0x808000) #define ALM_RTC_INST_SIZE (ALM_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND) #define ALM_RTC_DATA_SIZE (ALM_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) -#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE #define IWL_MAX_INST_SIZE ALM_RTC_INST_SIZE #define IWL_MAX_DATA_SIZE ALM_RTC_DATA_SIZE + +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL_MAX_BSM_SIZE ALM_RTC_INST_SIZE + #define IWL_MAX_NUM_QUEUES 8 -static inline int iwl_hw_valid_rtc_data_addr(u32 addr) +static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) { return (addr >= RTC_DATA_LOWER_BOUND) && (addr < ALM_RTC_DATA_UPPER_BOUND); } -/* Base physical address of iwl_shared is provided to FH_TSSR_CBB_BASE - * and &iwl_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ -struct iwl_shared { +/* Base physical address of iwl3945_shared is provided to FH_TSSR_CBB_BASE + * and &iwl3945_shared.rx_read_ptr[0] is provided to FH_RCSR_RPTR_ADDR(0) */ +struct iwl3945_shared { __le32 tx_base_ptr[8]; __le32 rx_read_ptr[3]; } __attribute__ ((packed)); -struct iwl_tfd_frame_data { +struct iwl3945_tfd_frame_data { __le32 addr; __le32 len; } __attribute__ ((packed)); -struct iwl_tfd_frame { +struct iwl3945_tfd_frame { __le32 control_flags; - struct iwl_tfd_frame_data pa[4]; + struct iwl3945_tfd_frame_data pa[4]; u8 reserved[28]; } __attribute__ ((packed)); -static inline u8 iwl_hw_get_rate(__le16 rate_n_flags) +static inline u8 iwl3945_hw_get_rate(__le16 rate_n_flags) { return le16_to_cpu(rate_n_flags) & 0xFF; } -static inline u16 iwl_hw_get_rate_n_flags(__le16 rate_n_flags) +static inline u16 iwl3945_hw_get_rate_n_flags(__le16 rate_n_flags) { return le16_to_cpu(rate_n_flags); } -static inline __le16 iwl_hw_set_rate_n_flags(u8 rate, u16 flags) +static inline __le16 iwl3945_hw_set_rate_n_flags(u8 rate, u16 flags) { return cpu_to_le16((u16)rate|flags); } diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-io.h b/drivers/net/wireless/iwlwifi/iwl-3945-io.h new file mode 100644 index 0000000..75e20d0 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-3945-io.h @@ -0,0 +1,431 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl3945_io_h__ +#define __iwl3945_io_h__ + +#include + +#include "iwl-3945-debug.h" + +/* + * IO, register, and NIC memory access functions + * + * NOTE on naming convention and macro usage for these + * + * A single _ prefix before a an access function means that no state + * check or debug information is printed when that function is called. + * + * A double __ prefix before an access function means that state is checked + * and the current line number is printed in addition to any other debug output. + * + * The non-prefixed name is the #define that maps the caller into a + * #define that provides the caller's __LINE__ to the double prefix version. + * + * If you wish to call the function without any debug or state checking, + * you should use the single _ prefix version (as is used by dependent IO + * routines, for example _iwl3945_read_direct32 calls the non-check version of + * _iwl3945_read32.) + * + * These declarations are *extremely* useful in quickly isolating code deltas + * which result in misconfiguring of the hardware I/O. In combination with + * git-bisect and the IO debug level you can quickly determine the specific + * commit which breaks the IO sequence to the hardware. + * + */ + +#define _iwl3945_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_write32(const char *f, u32 l, struct iwl3945_priv *iwl, + u32 ofs, u32 val) +{ + IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); + _iwl3945_write32(iwl, ofs, val); +} +#define iwl3945_write32(iwl, ofs, val) \ + __iwl3945_write32(__FILE__, __LINE__, iwl, ofs, val) +#else +#define iwl3945_write32(iwl, ofs, val) _iwl3945_write32(iwl, ofs, val) +#endif + +#define _iwl3945_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) +#ifdef CONFIG_IWL3945_DEBUG +static inline u32 __iwl3945_read32(char *f, u32 l, struct iwl3945_priv *iwl, u32 ofs) +{ + IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); + return _iwl3945_read32(iwl, ofs); +} +#define iwl3945_read32(iwl, ofs) __iwl3945_read32(__FILE__, __LINE__, iwl, ofs) +#else +#define iwl3945_read32(p, o) _iwl3945_read32(p, o) +#endif + +static inline int _iwl3945_poll_bit(struct iwl3945_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int i = 0; + + do { + if ((_iwl3945_read32(priv, addr) & mask) == (bits & mask)) + return i; + mdelay(10); + i += 10; + } while (i < timeout); + + return -ETIMEDOUT; +} +#ifdef CONFIG_IWL3945_DEBUG +static inline int __iwl3945_poll_bit(const char *f, u32 l, + struct iwl3945_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout); + if (unlikely(ret == -ETIMEDOUT)) + IWL_DEBUG_IO + ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", + addr, bits, mask, f, l); + else + IWL_DEBUG_IO + ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", + addr, bits, mask, ret, f, l); + return ret; +} +#define iwl3945_poll_bit(iwl, addr, bits, mask, timeout) \ + __iwl3945_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) +#else +#define iwl3945_poll_bit(p, a, b, m, t) _iwl3945_poll_bit(p, a, b, m, t) +#endif + +static inline void _iwl3945_set_bit(struct iwl3945_priv *priv, u32 reg, u32 mask) +{ + _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) | mask); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_set_bit(const char *f, u32 l, + struct iwl3945_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl3945_read32(priv, reg) | mask; + IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); + _iwl3945_write32(priv, reg, val); +} +#define iwl3945_set_bit(p, r, m) __iwl3945_set_bit(__FILE__, __LINE__, p, r, m) +#else +#define iwl3945_set_bit(p, r, m) _iwl3945_set_bit(p, r, m) +#endif + +static inline void _iwl3945_clear_bit(struct iwl3945_priv *priv, u32 reg, u32 mask) +{ + _iwl3945_write32(priv, reg, _iwl3945_read32(priv, reg) & ~mask); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_clear_bit(const char *f, u32 l, + struct iwl3945_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl3945_read32(priv, reg) & ~mask; + IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); + _iwl3945_write32(priv, reg, val); +} +#define iwl3945_clear_bit(p, r, m) __iwl3945_clear_bit(__FILE__, __LINE__, p, r, m) +#else +#define iwl3945_clear_bit(p, r, m) _iwl3945_clear_bit(p, r, m) +#endif + +static inline int _iwl3945_grab_nic_access(struct iwl3945_priv *priv) +{ + int ret; + u32 gp_ctl; + +#ifdef CONFIG_IWL3945_DEBUG + if (atomic_read(&priv->restrict_refcnt)) + return 0; +#endif + if (test_bit(STATUS_RF_KILL_HW, &priv->status) || + test_bit(STATUS_RF_KILL_SW, &priv->status)) { + IWL_WARNING("WARNING: Requesting MAC access during RFKILL " + "wakes up NIC\n"); + + /* 10 msec allows time for NIC to complete its data save */ + gp_ctl = _iwl3945_read32(priv, CSR_GP_CNTRL); + if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) { + IWL_DEBUG_RF_KILL("Wait for complete power-down, " + "gpctl = 0x%08x\n", gp_ctl); + mdelay(10); + } else + IWL_DEBUG_RF_KILL("power-down complete, " + "gpctl = 0x%08x\n", gp_ctl); + } + + /* this bit wakes up the NIC */ + _iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + ret = _iwl3945_poll_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50); + if (ret < 0) { + IWL_ERROR("MAC is in deep sleep!\n"); + return -EIO; + } + +#ifdef CONFIG_IWL3945_DEBUG + atomic_inc(&priv->restrict_refcnt); +#endif + return 0; +} + +#ifdef CONFIG_IWL3945_DEBUG +static inline int __iwl3945_grab_nic_access(const char *f, u32 l, + struct iwl3945_priv *priv) +{ + if (atomic_read(&priv->restrict_refcnt)) + IWL_DEBUG_INFO("Grabbing access while already held at " + "line %d.\n", l); + + IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); + return _iwl3945_grab_nic_access(priv); +} +#define iwl3945_grab_nic_access(priv) \ + __iwl3945_grab_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl3945_grab_nic_access(priv) \ + _iwl3945_grab_nic_access(priv) +#endif + +static inline void _iwl3945_release_nic_access(struct iwl3945_priv *priv) +{ +#ifdef CONFIG_IWL3945_DEBUG + if (atomic_dec_and_test(&priv->restrict_refcnt)) +#endif + _iwl3945_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_release_nic_access(const char *f, u32 l, + struct iwl3945_priv *priv) +{ + if (atomic_read(&priv->restrict_refcnt) <= 0) + IWL_ERROR("Release unheld nic access at line %d.\n", l); + + IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); + _iwl3945_release_nic_access(priv); +} +#define iwl3945_release_nic_access(priv) \ + __iwl3945_release_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl3945_release_nic_access(priv) \ + _iwl3945_release_nic_access(priv) +#endif + +static inline u32 _iwl3945_read_direct32(struct iwl3945_priv *priv, u32 reg) +{ + return _iwl3945_read32(priv, reg); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline u32 __iwl3945_read_direct32(const char *f, u32 l, + struct iwl3945_priv *priv, u32 reg) +{ + u32 value = _iwl3945_read_direct32(priv, reg); + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from %s %d\n", f, l); + IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, + f, l); + return value; +} +#define iwl3945_read_direct32(priv, reg) \ + __iwl3945_read_direct32(__FILE__, __LINE__, priv, reg) +#else +#define iwl3945_read_direct32 _iwl3945_read_direct32 +#endif + +static inline void _iwl3945_write_direct32(struct iwl3945_priv *priv, + u32 reg, u32 value) +{ + _iwl3945_write32(priv, reg, value); +} +#ifdef CONFIG_IWL3945_DEBUG +static void __iwl3945_write_direct32(u32 line, + struct iwl3945_priv *priv, u32 reg, u32 value) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + _iwl3945_write_direct32(priv, reg, value); +} +#define iwl3945_write_direct32(priv, reg, value) \ + __iwl3945_write_direct32(__LINE__, priv, reg, value) +#else +#define iwl3945_write_direct32 _iwl3945_write_direct32 +#endif + +static inline void iwl3945_write_reg_buf(struct iwl3945_priv *priv, + u32 reg, u32 len, u32 *values) +{ + u32 count = sizeof(u32); + + if ((priv != NULL) && (values != NULL)) { + for (; 0 < len; len -= count, reg += count, values++) + _iwl3945_write_direct32(priv, reg, *values); + } +} + +static inline int _iwl3945_poll_direct_bit(struct iwl3945_priv *priv, + u32 addr, u32 mask, int timeout) +{ + int i = 0; + + do { + if ((_iwl3945_read_direct32(priv, addr) & mask) == mask) + return i; + mdelay(10); + i += 10; + } while (i < timeout); + + return -ETIMEDOUT; +} + +#ifdef CONFIG_IWL3945_DEBUG +static inline int __iwl3945_poll_direct_bit(const char *f, u32 l, + struct iwl3945_priv *priv, + u32 addr, u32 mask, int timeout) +{ + int ret = _iwl3945_poll_direct_bit(priv, addr, mask, timeout); + + if (unlikely(ret == -ETIMEDOUT)) + IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - " + "timedout - %s %d\n", addr, mask, f, l); + else + IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " + "- %s %d\n", addr, mask, ret, f, l); + return ret; +} +#define iwl3945_poll_direct_bit(iwl, addr, mask, timeout) \ + __iwl3945_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) +#else +#define iwl3945_poll_direct_bit _iwl3945_poll_direct_bit +#endif + +static inline u32 _iwl3945_read_prph(struct iwl3945_priv *priv, u32 reg) +{ + _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + return _iwl3945_read_direct32(priv, HBUS_TARG_PRPH_RDAT); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline u32 __iwl3945_read_prph(u32 line, struct iwl3945_priv *priv, u32 reg) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + return _iwl3945_read_prph(priv, reg); +} + +#define iwl3945_read_prph(priv, reg) \ + __iwl3945_read_prph(__LINE__, priv, reg) +#else +#define iwl3945_read_prph _iwl3945_read_prph +#endif + +static inline void _iwl3945_write_prph(struct iwl3945_priv *priv, + u32 addr, u32 val) +{ + _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WADDR, + ((addr & 0x0000FFFF) | (3 << 24))); + _iwl3945_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); +} +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_write_prph(u32 line, struct iwl3945_priv *priv, + u32 addr, u32 val) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access from line %d\n", line); + _iwl3945_write_prph(priv, addr, val); +} + +#define iwl3945_write_prph(priv, addr, val) \ + __iwl3945_write_prph(__LINE__, priv, addr, val); +#else +#define iwl3945_write_prph _iwl3945_write_prph +#endif + +#define _iwl3945_set_bits_prph(priv, reg, mask) \ + _iwl3945_write_prph(priv, reg, (_iwl3945_read_prph(priv, reg) | mask)) +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_set_bits_prph(u32 line, struct iwl3945_priv *priv, + u32 reg, u32 mask) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + + _iwl3945_set_bits_prph(priv, reg, mask); +} +#define iwl3945_set_bits_prph(priv, reg, mask) \ + __iwl3945_set_bits_prph(__LINE__, priv, reg, mask) +#else +#define iwl3945_set_bits_prph _iwl3945_set_bits_prph +#endif + +#define _iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \ + _iwl3945_write_prph(priv, reg, ((_iwl3945_read_prph(priv, reg) & mask) | bits)) + +#ifdef CONFIG_IWL3945_DEBUG +static inline void __iwl3945_set_bits_mask_prph(u32 line, + struct iwl3945_priv *priv, u32 reg, u32 bits, u32 mask) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + _iwl3945_set_bits_mask_prph(priv, reg, bits, mask); +} +#define iwl3945_set_bits_mask_prph(priv, reg, bits, mask) \ + __iwl3945_set_bits_mask_prph(__LINE__, priv, reg, bits, mask) +#else +#define iwl3945_set_bits_mask_prph _iwl3945_set_bits_mask_prph +#endif + +static inline void iwl3945_clear_bits_prph(struct iwl3945_priv + *priv, u32 reg, u32 mask) +{ + u32 val = _iwl3945_read_prph(priv, reg); + _iwl3945_write_prph(priv, reg, (val & ~mask)); +} + +static inline u32 iwl3945_read_targ_mem(struct iwl3945_priv *priv, u32 addr) +{ + iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); + return iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); +} + +static inline void iwl3945_write_targ_mem(struct iwl3945_priv *priv, u32 addr, u32 val) +{ + iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); +} + +static inline void iwl3945_write_targ_mem_buf(struct iwl3945_priv *priv, u32 addr, + u32 len, u32 *values) +{ + iwl3945_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + for (; 0 < len; len -= sizeof(u32), values++) + iwl3945_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); +} +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index c48b1b5..adcd106 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -37,15 +37,13 @@ #include -#define IWL 3945 - #include "../net/mac80211/ieee80211_rate.h" -#include "iwlwifi.h" +#include "iwl-3945.h" #define RS_NAME "iwl-3945-rs" -struct iwl_rate_scale_data { +struct iwl3945_rate_scale_data { u64 data; s32 success_counter; s32 success_ratio; @@ -54,7 +52,7 @@ struct iwl_rate_scale_data { unsigned long stamp; }; -struct iwl_rate_scale_priv { +struct iwl3945_rate_scale_priv { spinlock_t lock; s32 *expected_tpt; unsigned long last_partial_flush; @@ -67,31 +65,31 @@ struct iwl_rate_scale_priv { u8 start_rate; u8 ibss_sta_added; struct timer_list rate_scale_flush; - struct iwl_rate_scale_data win[IWL_RATE_COUNT]; + struct iwl3945_rate_scale_data win[IWL_RATE_COUNT]; }; -static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = { +static s32 iwl3945_expected_tpt_g[IWL_RATE_COUNT] = { 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 }; -static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = { +static s32 iwl3945_expected_tpt_g_prot[IWL_RATE_COUNT] = { 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 }; -static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = { +static s32 iwl3945_expected_tpt_a[IWL_RATE_COUNT] = { 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 }; -static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = { +static s32 iwl3945_expected_tpt_b[IWL_RATE_COUNT] = { 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 }; -struct iwl_tpt_entry { +struct iwl3945_tpt_entry { s8 min_rssi; u8 index; }; -static struct iwl_tpt_entry iwl_tpt_table_a[] = { +static struct iwl3945_tpt_entry iwl3945_tpt_table_a[] = { {-60, IWL_RATE_54M_INDEX}, {-64, IWL_RATE_48M_INDEX}, {-72, IWL_RATE_36M_INDEX}, @@ -102,7 +100,7 @@ static struct iwl_tpt_entry iwl_tpt_table_a[] = { {-89, IWL_RATE_6M_INDEX} }; -static struct iwl_tpt_entry iwl_tpt_table_b[] = { +static struct iwl3945_tpt_entry iwl3945_tpt_table_b[] = { {-86, IWL_RATE_11M_INDEX}, {-88, IWL_RATE_5M_INDEX}, {-90, IWL_RATE_2M_INDEX}, @@ -110,7 +108,7 @@ static struct iwl_tpt_entry iwl_tpt_table_b[] = { }; -static struct iwl_tpt_entry iwl_tpt_table_g[] = { +static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { {-60, IWL_RATE_54M_INDEX}, {-64, IWL_RATE_48M_INDEX}, {-68, IWL_RATE_36M_INDEX}, @@ -131,30 +129,30 @@ static struct iwl_tpt_entry iwl_tpt_table_g[] = { #define IWL_RATE_MIN_SUCCESS_TH 8 #define IWL_RATE_DECREASE_TH 1920 -static u8 iwl_get_rate_index_by_rssi(s32 rssi, u8 mode) +static u8 iwl3945_get_rate_index_by_rssi(s32 rssi, u8 mode) { u32 index = 0; u32 table_size = 0; - struct iwl_tpt_entry *tpt_table = NULL; + struct iwl3945_tpt_entry *tpt_table = NULL; if ((rssi < IWL_MIN_RSSI_VAL) || (rssi > IWL_MAX_RSSI_VAL)) rssi = IWL_MIN_RSSI_VAL; switch (mode) { case MODE_IEEE80211G: - tpt_table = iwl_tpt_table_g; - table_size = ARRAY_SIZE(iwl_tpt_table_g); + tpt_table = iwl3945_tpt_table_g; + table_size = ARRAY_SIZE(iwl3945_tpt_table_g); break; case MODE_IEEE80211A: - tpt_table = iwl_tpt_table_a; - table_size = ARRAY_SIZE(iwl_tpt_table_a); + tpt_table = iwl3945_tpt_table_a; + table_size = ARRAY_SIZE(iwl3945_tpt_table_a); break; default: case MODE_IEEE80211B: - tpt_table = iwl_tpt_table_b; - table_size = ARRAY_SIZE(iwl_tpt_table_b); + tpt_table = iwl3945_tpt_table_b; + table_size = ARRAY_SIZE(iwl3945_tpt_table_b); break; } @@ -166,7 +164,7 @@ static u8 iwl_get_rate_index_by_rssi(s32 rssi, u8 mode) return tpt_table[index].index; } -static void iwl_clear_window(struct iwl_rate_scale_data *window) +static void iwl3945_clear_window(struct iwl3945_rate_scale_data *window) { window->data = 0; window->success_counter = 0; @@ -177,13 +175,13 @@ static void iwl_clear_window(struct iwl_rate_scale_data *window) } /** - * iwl_rate_scale_flush_windows - flush out the rate scale windows + * iwl3945_rate_scale_flush_windows - flush out the rate scale windows * * Returns the number of windows that have gathered data but were * not flushed. If there were any that were not flushed, then * reschedule the rate flushing routine. */ -static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv) +static int iwl3945_rate_scale_flush_windows(struct iwl3945_rate_scale_priv *rs_priv) { int unflushed = 0; int i; @@ -204,7 +202,7 @@ static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv) IWL_DEBUG_RATE("flushing %d samples of rate " "index %d\n", rs_priv->win[i].counter, i); - iwl_clear_window(&rs_priv->win[i]); + iwl3945_clear_window(&rs_priv->win[i]); } else unflushed++; spin_unlock_irqrestore(&rs_priv->lock, flags); @@ -216,16 +214,16 @@ static int iwl_rate_scale_flush_windows(struct iwl_rate_scale_priv *rs_priv) #define IWL_RATE_FLUSH_MAX 5000 /* msec */ #define IWL_RATE_FLUSH_MIN 50 /* msec */ -static void iwl_bg_rate_scale_flush(unsigned long data) +static void iwl3945_bg_rate_scale_flush(unsigned long data) { - struct iwl_rate_scale_priv *rs_priv = (void *)data; + struct iwl3945_rate_scale_priv *rs_priv = (void *)data; int unflushed = 0; unsigned long flags; u32 packet_count, duration, pps; IWL_DEBUG_RATE("enter\n"); - unflushed = iwl_rate_scale_flush_windows(rs_priv); + unflushed = iwl3945_rate_scale_flush_windows(rs_priv); spin_lock_irqsave(&rs_priv->lock, flags); @@ -279,14 +277,14 @@ static void iwl_bg_rate_scale_flush(unsigned long data) } /** - * iwl_collect_tx_data - Update the success/failure sliding window + * iwl3945_collect_tx_data - Update the success/failure sliding window * * We keep a sliding window of the last 64 packets transmitted * at this rate. window->data contains the bitmask of successful * packets. */ -static void iwl_collect_tx_data(struct iwl_rate_scale_priv *rs_priv, - struct iwl_rate_scale_data *window, +static void iwl3945_collect_tx_data(struct iwl3945_rate_scale_priv *rs_priv, + struct iwl3945_rate_scale_data *window, int success, int retries) { unsigned long flags; @@ -362,7 +360,7 @@ static void *rs_alloc(struct ieee80211_local *local) return local->hw.priv; } -/* rate scale requires free function to be implmented */ +/* rate scale requires free function to be implemented */ static void rs_free(void *priv) { return; @@ -375,12 +373,12 @@ static void rs_clear(void *priv) static void *rs_alloc_sta(void *priv, gfp_t gfp) { - struct iwl_rate_scale_priv *rs_priv; + struct iwl3945_rate_scale_priv *rs_priv; int i; IWL_DEBUG_RATE("enter\n"); - rs_priv = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp); + rs_priv = kzalloc(sizeof(struct iwl3945_rate_scale_priv), gfp); if (!rs_priv) { IWL_DEBUG_RATE("leave: ENOMEM\n"); return NULL; @@ -391,7 +389,7 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp) rs_priv->start_rate = IWL_RATE_INVALID; /* default to just 802.11b */ - rs_priv->expected_tpt = iwl_expected_tpt_b; + rs_priv->expected_tpt = iwl3945_expected_tpt_b; rs_priv->last_partial_flush = jiffies; rs_priv->last_flush = jiffies; @@ -401,10 +399,10 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp) init_timer(&rs_priv->rate_scale_flush); rs_priv->rate_scale_flush.data = (unsigned long)rs_priv; - rs_priv->rate_scale_flush.function = &iwl_bg_rate_scale_flush; + rs_priv->rate_scale_flush.function = &iwl3945_bg_rate_scale_flush; for (i = 0; i < IWL_RATE_COUNT; i++) - iwl_clear_window(&rs_priv->win[i]); + iwl3945_clear_window(&rs_priv->win[i]); IWL_DEBUG_RATE("leave\n"); @@ -413,7 +411,7 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp) static void rs_free_sta(void *priv, void *priv_sta) { - struct iwl_rate_scale_priv *rs_priv = priv_sta; + struct iwl3945_rate_scale_priv *rs_priv = priv_sta; IWL_DEBUG_RATE("enter\n"); del_timer_sync(&rs_priv->rate_scale_flush); @@ -427,9 +425,9 @@ static void rs_free_sta(void *priv, void *priv_sta) * for A and B mode we need to overright prev * value */ -static int rs_adjust_next_rate(struct iwl_priv *priv, int rate) +static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) { - int next_rate = iwl_get_prev_ieee_rate(rate); + int next_rate = iwl3945_get_prev_ieee_rate(rate); switch (priv->phymode) { case MODE_IEEE80211A: @@ -451,7 +449,7 @@ static int rs_adjust_next_rate(struct iwl_priv *priv, int rate) /** * rs_tx_status - Update rate control values based on Tx results * - * NOTE: Uses iwl_priv->retry_rate for the # of retries attempted by + * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by * the hardware for each rate. */ static void rs_tx_status(void *priv_rate, @@ -464,9 +462,9 @@ static void rs_tx_status(void *priv_rate, unsigned long flags; struct sta_info *sta; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct iwl_rate_scale_priv *rs_priv; + struct iwl3945_rate_scale_priv *rs_priv; IWL_DEBUG_RATE("enter\n"); @@ -516,7 +514,7 @@ static void rs_tx_status(void *priv_rate, /* Update this rate accounting for as many retries * as was used for it (per current_count) */ - iwl_collect_tx_data(rs_priv, + iwl3945_collect_tx_data(rs_priv, &rs_priv->win[scale_rate_index], 0, current_count); IWL_DEBUG_RATE("Update rate %d for %d retries.\n", @@ -535,7 +533,7 @@ static void rs_tx_status(void *priv_rate, last_index, (tx_resp->flags & IEEE80211_TX_STATUS_ACK) ? "success" : "failure"); - iwl_collect_tx_data(rs_priv, + iwl3945_collect_tx_data(rs_priv, &rs_priv->win[last_index], tx_resp->flags & IEEE80211_TX_STATUS_ACK, 1); @@ -562,7 +560,7 @@ static void rs_tx_status(void *priv_rate, return; } -static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local +static struct ieee80211_rate *iwl3945_get_lowest_rate(struct ieee80211_local *local) { struct ieee80211_hw_mode *mode = local->oper_hw_mode; @@ -578,13 +576,13 @@ static struct ieee80211_rate *iwl_get_lowest_rate(struct ieee80211_local return &mode->rates[0]; } -static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv, +static u16 iwl3945_get_adjacent_rate(struct iwl3945_rate_scale_priv *rs_priv, u8 index, u16 rate_mask, int phymode) { u8 high = IWL_RATE_INVALID; u8 low = IWL_RATE_INVALID; - /* 802.11A walks to the next literal adjascent rate in + /* 802.11A walks to the next literal adjacent rate in * the rate table */ if (unlikely(phymode == MODE_IEEE80211A)) { int i; @@ -614,9 +612,9 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv, low = index; while (low != IWL_RATE_INVALID) { if (rs_priv->tgg) - low = iwl_rates[low].prev_rs_tgg; + low = iwl3945_rates[low].prev_rs_tgg; else - low = iwl_rates[low].prev_rs; + low = iwl3945_rates[low].prev_rs; if (low == IWL_RATE_INVALID) break; if (rate_mask & (1 << low)) @@ -627,9 +625,9 @@ static u16 iwl_get_adjacent_rate(struct iwl_rate_scale_priv *rs_priv, high = index; while (high != IWL_RATE_INVALID) { if (rs_priv->tgg) - high = iwl_rates[high].next_rs_tgg; + high = iwl3945_rates[high].next_rs_tgg; else - high = iwl_rates[high].next_rs; + high = iwl3945_rates[high].next_rs; if (high == IWL_RATE_INVALID) break; if (rate_mask & (1 << high)) @@ -665,8 +663,8 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, u8 high = IWL_RATE_INVALID; u16 high_low; int index; - struct iwl_rate_scale_priv *rs_priv; - struct iwl_rate_scale_data *window = NULL; + struct iwl3945_rate_scale_priv *rs_priv; + struct iwl3945_rate_scale_data *window = NULL; int current_tpt = IWL_INVALID_VALUE; int low_tpt = IWL_INVALID_VALUE; int high_tpt = IWL_INVALID_VALUE; @@ -677,7 +675,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct sta_info *sta; u16 fc, rate_mask; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; DECLARE_MAC_BUF(mac); IWL_DEBUG_RATE("enter\n"); @@ -693,7 +691,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, IWL_DEBUG_RATE("leave: lowest rate (not data or is " "multicast)\n"); - return iwl_get_lowest_rate(local); + return iwl3945_get_lowest_rate(local); } sta = sta_info_get(local, hdr->addr1); @@ -714,12 +712,12 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !rs_priv->ibss_sta_added) { - u8 sta_id = iwl_hw_find_station(priv, hdr->addr1); + u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", print_mac(mac, hdr->addr1)); - sta_id = iwl_add_station(priv, + sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC); } if (sta_id != IWL_INVALID_STATION) @@ -757,7 +755,7 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, rs_priv->expected_tpt[index] + 64) / 128); current_tpt = window->average_tpt; - high_low = iwl_get_adjacent_rate(rs_priv, index, rate_mask, + high_low = iwl3945_get_adjacent_rate(rs_priv, index, rate_mask, local->hw.conf.phymode); low = high_low & 0xff; high = (high_low >> 8) & 0xff; @@ -862,11 +860,11 @@ static struct rate_control_ops rs_ops = { .free_sta = rs_free_sta, }; -int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) +int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) { struct ieee80211_local *local = hw_to_local(hw); - struct iwl_priv *priv = hw->priv; - struct iwl_rate_scale_priv *rs_priv; + struct iwl3945_priv *priv = hw->priv; + struct iwl3945_rate_scale_priv *rs_priv; struct sta_info *sta; unsigned long flags; int count = 0, i; @@ -892,7 +890,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) int j; count += - sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2); + sprintf(&buf[count], " %2dMbs: ", iwl3945_rates[i].ieee / 2); mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1)); for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1) @@ -901,7 +899,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) samples += rs_priv->win[i].counter; good += rs_priv->win[i].success_counter; - success += rs_priv->win[i].success_counter * iwl_rates[i].ieee; + success += rs_priv->win[i].success_counter * iwl3945_rates[i].ieee; if (rs_priv->win[i].stamp) { int delta = @@ -914,7 +912,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) } else buf[count++] = '\n'; - j = iwl_get_prev_ieee_rate(i); + j = iwl3945_get_prev_ieee_rate(i); if (j == i) break; i = j; @@ -925,7 +923,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) /* Display the average rate of all samples taken. * * NOTE: We multiple # of samples by 2 since the IEEE measurement - * added from iwl_rates is actually 2X the rate */ + * added from iwl3945_rates is actually 2X the rate */ if (samples) count += sprintf( &buf[count], @@ -939,13 +937,13 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) return count; } -void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) +void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; s32 rssi = 0; unsigned long flags; struct ieee80211_local *local = hw_to_local(hw); - struct iwl_rate_scale_priv *rs_priv; + struct iwl3945_rate_scale_priv *rs_priv; struct sta_info *sta; IWL_DEBUG_RATE("enter\n"); @@ -974,19 +972,19 @@ void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) case MODE_IEEE80211G: if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { rs_priv->tgg = 1; - rs_priv->expected_tpt = iwl_expected_tpt_g_prot; + rs_priv->expected_tpt = iwl3945_expected_tpt_g_prot; } else - rs_priv->expected_tpt = iwl_expected_tpt_g; + rs_priv->expected_tpt = iwl3945_expected_tpt_g; break; case MODE_IEEE80211A: - rs_priv->expected_tpt = iwl_expected_tpt_a; + rs_priv->expected_tpt = iwl3945_expected_tpt_a; break; default: IWL_WARNING("Invalid phymode. Defaulting to 802.11b\n"); case MODE_IEEE80211B: - rs_priv->expected_tpt = iwl_expected_tpt_b; + rs_priv->expected_tpt = iwl3945_expected_tpt_b; break; } @@ -999,19 +997,19 @@ void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) IWL_DEBUG(IWL_DL_INFO | IWL_DL_RATE, "Network RSSI: %d\n", rssi); - rs_priv->start_rate = iwl_get_rate_index_by_rssi(rssi, priv->phymode); + rs_priv->start_rate = iwl3945_get_rate_index_by_rssi(rssi, priv->phymode); IWL_DEBUG_RATE("leave: rssi %d assign rate index: " "%d (plcp 0x%x)\n", rssi, rs_priv->start_rate, - iwl_rates[rs_priv->start_rate].plcp); + iwl3945_rates[rs_priv->start_rate].plcp); } -void iwl_rate_control_register(struct ieee80211_hw *hw) +void iwl3945_rate_control_register(struct ieee80211_hw *hw) { ieee80211_rate_control_register(&rs_ops); } -void iwl_rate_control_unregister(struct ieee80211_hw *hw) +void iwl3945_rate_control_unregister(struct ieee80211_hw *hw) { ieee80211_rate_control_unregister(&rs_ops); } diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h index bec4d3f..e21a5ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h @@ -27,9 +27,9 @@ #ifndef __iwl_3945_rs_h__ #define __iwl_3945_rs_h__ -struct iwl_rate_info { - u8 plcp; - u8 ieee; +struct iwl3945_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ u8 prev_ieee; /* previous rate in IEEE speeds */ u8 next_ieee; /* next rate in IEEE speeds */ u8 prev_rs; /* previous rate used in rs algo */ @@ -38,9 +38,12 @@ struct iwl_rate_info { u8 next_rs_tgg; /* next rate used in TGG rs algo */ u8 table_rs_index; /* index in rate scale table cmd */ u8 prev_table_rs; /* prev in rate table cmd */ - }; +/* + * These serve as indexes into + * struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT]; + */ enum { IWL_RATE_1M_INDEX = 0, IWL_RATE_2M_INDEX, @@ -96,6 +99,7 @@ enum { #define IWL_RATE_5M_MASK (1< -#define IWL 3945 - -#include "iwlwifi.h" -#include "iwl-helpers.h" #include "iwl-3945.h" +#include "iwl-helpers.h" #include "iwl-3945-rs.h" #define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \ @@ -66,7 +63,7 @@ * maps to IWL_RATE_INVALID * */ -const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { +const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2), /* 1mbps */ IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5), /* 2mbps */ IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11), /*5.5mbps */ @@ -81,12 +78,12 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ }; -/* 1 = enable the iwl_disable_events() function */ +/* 1 = enable the iwl3945_disable_events() function */ #define IWL_EVT_DISABLE (0) #define IWL_EVT_DISABLE_SIZE (1532/32) /** - * iwl_disable_events - Disable selected events in uCode event log + * iwl3945_disable_events - Disable selected events in uCode event log * * Disable an event by writing "1"s into "disable" * bitmap in SRAM. Bit position corresponds to Event # (id/type). @@ -94,9 +91,9 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { * Use for only special debugging. This function is just a placeholder as-is, * you'll need to provide the special bits! ... * ... and set IWL_EVT_DISABLE to 1. */ -void iwl_disable_events(struct iwl_priv *priv) +void iwl3945_disable_events(struct iwl3945_priv *priv) { - int rc; + int ret; int i; u32 base; /* SRAM address of event log header */ u32 disable_ptr; /* SRAM address of event-disable bitmap array */ @@ -152,32 +149,31 @@ void iwl_disable_events(struct iwl_priv *priv) }; base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl_hw_valid_rtc_data_addr(base)) { + if (!iwl3945_hw_valid_rtc_data_addr(base)) { IWL_ERROR("Invalid event log pointer 0x%08X\n", base); return; } - rc = iwl_grab_restricted_access(priv); - if (rc) { + ret = iwl3945_grab_nic_access(priv); + if (ret) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } - disable_ptr = iwl_read_restricted_mem(priv, base + (4 * sizeof(u32))); - array_size = iwl_read_restricted_mem(priv, base + (5 * sizeof(u32))); - iwl_release_restricted_access(priv); + disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32))); + array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32))); + iwl3945_release_nic_access(priv); if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) { IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n", disable_ptr); - rc = iwl_grab_restricted_access(priv); + ret = iwl3945_grab_nic_access(priv); for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++) - iwl_write_restricted_mem(priv, - disable_ptr + - (i * sizeof(u32)), - evt_disable[i]); + iwl3945_write_targ_mem(priv, + disable_ptr + (i * sizeof(u32)), + evt_disable[i]); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } else { IWL_DEBUG_INFO("Selected uCode log events may be disabled\n"); IWL_DEBUG_INFO(" by writing \"1\"s into disable bitmap\n"); @@ -198,7 +194,7 @@ void iwl_disable_events(struct iwl_priv *priv) * IWL_ANTENNA_MAIN - Force MAIN antenna * IWL_ANTENNA_AUX - Force AUX antenna */ -__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) +__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv) { switch (priv->antenna) { case IWL_ANTENNA_DIVERSITY: @@ -230,11 +226,11 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv) * *****************************************************************************/ -void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n", - (int)sizeof(struct iwl_notif_statistics), + (int)sizeof(struct iwl3945_notif_statistics), le32_to_cpu(pkt->len)); memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics)); @@ -242,15 +238,15 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) priv->last_statistics_time = jiffies; } -static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data, - struct iwl_rx_mem_buffer *rxb, +static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data, + struct iwl3945_rx_mem_buffer *rxb, struct ieee80211_rx_status *stats, u16 phy_flags) { struct ieee80211_hdr *hdr; - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; - struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt); + struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); short len = le16_to_cpu(rx_hdr->len); /* We received data from the HW, so stop the watchdog */ @@ -266,11 +262,11 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data, return; } if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { - if (iwl_param_hwcrypto) - iwl_set_decrypted_flag(priv, rxb->skb, + if (iwl3945_param_hwcrypto) + iwl3945_set_decrypted_flag(priv, rxb->skb, le32_to_cpu(rx_end->status), stats); - iwl_handle_data_packet_monitor(priv, rxb, IWL_RX_DATA(pkt), + iwl3945_handle_data_packet_monitor(priv, rxb, IWL_RX_DATA(pkt), len, stats, phy_flags); return; } @@ -281,21 +277,23 @@ static void iwl3945_handle_data_packet(struct iwl_priv *priv, int is_data, hdr = (void *)rxb->skb->data; - if (iwl_param_hwcrypto) - iwl_set_decrypted_flag(priv, rxb->skb, + if (iwl3945_param_hwcrypto) + iwl3945_set_decrypted_flag(priv, rxb->skb, le32_to_cpu(rx_end->status), stats); ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); rxb->skb = NULL; } -static void iwl3945_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + +static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt); + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); struct ieee80211_hdr *header; u16 phy_flags = le16_to_cpu(rx_hdr->phy_flags); u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg); @@ -351,14 +349,14 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, * Calculate stats.signal (quality indicator in %) based on SNR. */ if (rx_stats_noise_diff) { snr = rx_stats_sig_avg / rx_stats_noise_diff; - stats.noise = stats.ssi - iwl_calc_db_from_ratio(snr); - stats.signal = iwl_calc_sig_qual(stats.ssi, stats.noise); + stats.noise = stats.ssi - iwl3945_calc_db_from_ratio(snr); + stats.signal = iwl3945_calc_sig_qual(stats.ssi, stats.noise); /* If noise info not available, calculate signal quality indicator (%) * using just the dBm signal level. */ } else { stats.noise = priv->last_rx_noise; - stats.signal = iwl_calc_sig_qual(stats.ssi, 0); + stats.signal = iwl3945_calc_sig_qual(stats.ssi, 0); } @@ -368,24 +366,24 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, stats.freq = ieee80211chan2mhz(stats.channel); - /* can be covered by iwl_report_frame() in most cases */ + /* can be covered by iwl3945_report_frame() in most cases */ /* IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */ header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt); - network_packet = iwl_is_network_packet(priv, header); + network_packet = iwl3945_is_network_packet(priv, header); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_STATS && net_ratelimit()) +#ifdef CONFIG_IWL3945_DEBUG + if (iwl3945_debug_level & IWL_DL_STATS && net_ratelimit()) IWL_DEBUG_STATS ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n", network_packet ? '*' : ' ', stats.channel, stats.ssi, stats.ssi, stats.ssi, stats.rate); - if (iwl_debug_level & (IWL_DL_RX)) + if (iwl3945_debug_level & (IWL_DL_RX)) /* Set "1" to report good data frames in groups of 100 */ - iwl_report_frame(priv, pkt, header, 1); + iwl3945_report_frame(priv, pkt, header, 1); #endif if (network_packet) { @@ -446,6 +444,13 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, case IEEE80211_STYPE_REASSOC_RESP:{ struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; + + /* We have just associated, give some + * time for the 4-way handshake if + * any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; + priv->assoc_id = (~((1 << 15) | (1 << 14)) & le16_to_cpu(mgnt->u. assoc_resp.aid)); @@ -485,7 +490,7 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, DECLARE_MAC_BUF(mac2); DECLARE_MAC_BUF(mac3); - if (unlikely(is_duplicate_packet(priv, header))) + if (unlikely(iwl3945_is_duplicate_packet(priv, header))) IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", print_mac(mac1, header->addr1), print_mac(mac2, header->addr2), @@ -498,12 +503,12 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, } } -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, +int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr, dma_addr_t addr, u16 len) { int count; u32 pad; - struct iwl_tfd_frame *tfd = (struct iwl_tfd_frame *)ptr; + struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr; count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags)); @@ -526,14 +531,14 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, } /** - * iwl_hw_txq_free_tfd - Free one TFD, those at index [txq->q.last_used] + * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr] * * Does NOT advance any indexes */ -int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) { - struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; - struct iwl_tfd_frame *bd = &bd_tmp[txq->q.last_used]; + struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0]; + struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; struct pci_dev *dev = priv->pci_dev; int i; int counter; @@ -556,19 +561,19 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) for (i = 1; i < counter; i++) { pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr), le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE); - if (txq->txb[txq->q.last_used].skb[0]) { - struct sk_buff *skb = txq->txb[txq->q.last_used].skb[0]; - if (txq->txb[txq->q.last_used].skb[0]) { + if (txq->txb[txq->q.read_ptr].skb[0]) { + struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0]; + if (txq->txb[txq->q.read_ptr].skb[0]) { /* Can be called from interrupt context */ dev_kfree_skb_any(skb); - txq->txb[txq->q.last_used].skb[0] = NULL; + txq->txb[txq->q.read_ptr].skb[0] = NULL; } } } return 0; } -u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) +u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) { int i; int ret = IWL_INVALID_STATION; @@ -592,11 +597,11 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) } /** - * iwl_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: + * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: * */ -void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_cmd *cmd, +void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, struct ieee80211_tx_control *ctrl, struct ieee80211_hdr *hdr, int sta_id, int tx_id) { @@ -609,7 +614,7 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, __le32 tx_flags; u16 fc = le16_to_cpu(hdr->frame_control); - rate = iwl_rates[rate_index].plcp; + rate = iwl3945_rates[rate_index].plcp; tx_flags = cmd->cmd.tx.tx_flags; /* We need to figure out how to get the sta->supp_rates while @@ -676,10 +681,10 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]); } -u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) +u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags) { unsigned long flags_spin; - struct iwl_station_entry *station; + struct iwl3945_station_entry *station; if (sta_id == IWL_INVALID_STATION) return IWL_INVALID_STATION; @@ -694,34 +699,19 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - iwl_send_add_station(priv, &station->sta, flags); + iwl3945_send_add_station(priv, &station->sta, flags); IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n", sta_id, tx_rate); return sta_id; } -void iwl_hw_card_show_info(struct iwl_priv *priv) -{ - IWL_DEBUG_INFO("3945ABG HW Version %u.%u.%u\n", - ((priv->eeprom.board_revision >> 8) & 0x0F), - ((priv->eeprom.board_revision >> 8) >> 4), - (priv->eeprom.board_revision & 0x00FF)); - - IWL_DEBUG_INFO("3945ABG PBA Number %.*s\n", - (int)sizeof(priv->eeprom.board_pba_number), - priv->eeprom.board_pba_number); - - IWL_DEBUG_INFO("EEPROM_ANTENNA_SWITCH_TYPE is 0x%02X\n", - priv->eeprom.antenna_switch_type); -} - -static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) +static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max) { int rc; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; @@ -733,23 +723,23 @@ static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) rc = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE, &val); if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) { - iwl_set_bits_mask_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, ~APMG_PS_CTRL_MSK_PWR_SRC); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); - iwl_poll_bit(priv, CSR_GPIO_IN, + iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VAUX_PWR_SRC, CSR_GPIO_IN_BIT_AUX_POWER, 5000); } else - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } else { - iwl_set_bits_mask_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~APMG_PS_CTRL_MSK_PWR_SRC); - iwl_release_restricted_access(priv); - iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, + iwl3945_release_nic_access(priv); + iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ } spin_unlock_irqrestore(&priv->lock, flags); @@ -757,24 +747,24 @@ static int iwl3945_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) return rc; } -static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) { int rc; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr); - iwl_write_restricted(priv, FH_RCSR_RPTR_ADDR(0), + iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr); + iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0), priv->hw_setting.shared_phys + - offsetof(struct iwl_shared, rx_read_ptr[0])); - iwl_write_restricted(priv, FH_RCSR_WPTR(0), 0); - iwl_write_restricted(priv, FH_RCSR_CONFIG(0), + offsetof(struct iwl3945_shared, rx_read_ptr[0])); + iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0); + iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE | ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE | ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN | @@ -785,44 +775,44 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH); /* fake read to flush all prev I/O */ - iwl_read_restricted(priv, FH_RSSR_CTRL); + iwl3945_read_direct32(priv, FH_RSSR_CTRL); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -static int iwl3945_tx_reset(struct iwl_priv *priv) +static int iwl3945_tx_reset(struct iwl3945_priv *priv) { int rc; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } /* bypass mode */ - iwl_write_restricted_reg(priv, SCD_MODE_REG, 0x2); + iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2); /* RA 0 is active */ - iwl_write_restricted_reg(priv, SCD_ARASTAT_REG, 0x01); + iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01); /* all 6 fifo are active */ - iwl_write_restricted_reg(priv, SCD_TXFACT_REG, 0x3f); + iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f); - iwl_write_restricted_reg(priv, SCD_SBYP_MODE_1_REG, 0x010000); - iwl_write_restricted_reg(priv, SCD_SBYP_MODE_2_REG, 0x030002); - iwl_write_restricted_reg(priv, SCD_TXF4MF_REG, 0x000004); - iwl_write_restricted_reg(priv, SCD_TXF5MF_REG, 0x000005); + iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000); + iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002); + iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004); + iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005); - iwl_write_restricted(priv, FH_TSSR_CBB_BASE, + iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE, priv->hw_setting.shared_phys); - iwl_write_restricted(priv, FH_TSSR_MSG_CONFIG, + iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG, ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B | @@ -831,7 +821,7 @@ static int iwl3945_tx_reset(struct iwl_priv *priv) ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH | ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -842,12 +832,12 @@ static int iwl3945_tx_reset(struct iwl_priv *priv) * * Destroys all DMA structures and initialize them again */ -static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) +static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv) { int rc; int txq_id, slots_num; - iwl_hw_txq_ctx_free(priv); + iwl3945_hw_txq_ctx_free(priv); /* Tx CMD queue */ rc = iwl3945_tx_reset(priv); @@ -858,7 +848,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) { slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, + rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); if (rc) { IWL_ERROR("Tx %d queue init failed\n", txq_id); @@ -869,26 +859,26 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) return rc; error: - iwl_hw_txq_ctx_free(priv); + iwl3945_hw_txq_ctx_free(priv); return rc; } -int iwl_hw_nic_init(struct iwl_priv *priv) +int iwl3945_hw_nic_init(struct iwl3945_priv *priv) { u8 rev_id; int rc; unsigned long flags; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl3945_rx_queue *rxq = &priv->rxq; - iwl_power_init_handle(priv); + iwl3945_power_init_handle(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24)); - iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, + iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24)); + iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); - iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - rc = iwl_poll_bit(priv, CSR_GP_CNTRL, + iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (rc < 0) { @@ -897,18 +887,18 @@ int iwl_hw_nic_init(struct iwl_priv *priv) return rc; } - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted_reg(priv, APMG_CLK_EN_REG, + iwl3945_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); udelay(20); - iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG, + iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); /* Determine HW type */ @@ -924,25 +914,25 @@ int iwl_hw_nic_init(struct iwl_priv *priv) IWL_DEBUG_INFO("RTP type \n"); else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { IWL_DEBUG_INFO("ALM-MB type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB); } else { IWL_DEBUG_INFO("ALM-MM type\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM); } spin_unlock_irqrestore(&priv->lock, flags); /* Initialize the EEPROM */ - rc = iwl_eeprom_init(priv); + rc = iwl3945_eeprom_init(priv); if (rc) return rc; spin_lock_irqsave(&priv->lock, flags); if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) { IWL_DEBUG_INFO("SKU OP mode is mrc\n"); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC); } else IWL_DEBUG_INFO("SKU OP mode is basic\n"); @@ -950,24 +940,24 @@ int iwl_hw_nic_init(struct iwl_priv *priv) if ((priv->eeprom.board_revision & 0xF0) == 0xD0) { IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", priv->eeprom.board_revision); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); } else { IWL_DEBUG_INFO("3945ABG revision is 0x%X\n", priv->eeprom.board_revision); - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE); } if (priv->eeprom.almgor_m_version <= 1) { - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A); IWL_DEBUG_INFO("Card M type A version is 0x%X\n", priv->eeprom.almgor_m_version); } else { IWL_DEBUG_INFO("Card M type B version is 0x%X\n", priv->eeprom.almgor_m_version); - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B); } spin_unlock_irqrestore(&priv->lock, flags); @@ -980,15 +970,15 @@ int iwl_hw_nic_init(struct iwl_priv *priv) /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { - rc = iwl_rx_queue_alloc(priv); + rc = iwl3945_rx_queue_alloc(priv); if (rc) { IWL_ERROR("Unable to initialize Rx queue\n"); return -ENOMEM; } } else - iwl_rx_queue_reset(priv, rxq); + iwl3945_rx_queue_reset(priv, rxq); - iwl_rx_replenish(priv); + iwl3945_rx_replenish(priv); iwl3945_rx_init(priv, rxq); @@ -996,16 +986,16 @@ int iwl_hw_nic_init(struct iwl_priv *priv) /* Look at using this instead: rxq->need_update = 1; - iwl_rx_queue_update_write_ptr(priv, rxq); + iwl3945_rx_queue_update_write_ptr(priv, rxq); */ - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted(priv, FH_RCSR_WPTR(0), rxq->write & ~7); - iwl_release_restricted_access(priv); + iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); @@ -1019,49 +1009,49 @@ int iwl_hw_nic_init(struct iwl_priv *priv) } /** - * iwl_hw_txq_ctx_free - Free TXQ Context + * iwl3945_hw_txq_ctx_free - Free TXQ Context * * Destroy all TX DMA queues and structures */ -void iwl_hw_txq_ctx_free(struct iwl_priv *priv) +void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv) { int txq_id; /* Tx queues */ for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) - iwl_tx_queue_free(priv, &priv->txq[txq_id]); + iwl3945_tx_queue_free(priv, &priv->txq[txq_id]); } -void iwl_hw_txq_ctx_stop(struct iwl_priv *priv) +void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv) { int queue; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - if (iwl_grab_restricted_access(priv)) { + if (iwl3945_grab_nic_access(priv)) { spin_unlock_irqrestore(&priv->lock, flags); - iwl_hw_txq_ctx_free(priv); + iwl3945_hw_txq_ctx_free(priv); return; } /* stop SCD */ - iwl_write_restricted_reg(priv, SCD_MODE_REG, 0); + iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0); /* reset TFD queues */ for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) { - iwl_write_restricted(priv, FH_TCSR_CONFIG(queue), 0x0); - iwl_poll_restricted_bit(priv, FH_TSSR_TX_STATUS, + iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0); + iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS, ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue), 1000); } - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); - iwl_hw_txq_ctx_free(priv); + iwl3945_hw_txq_ctx_free(priv); } -int iwl_hw_nic_stop_master(struct iwl_priv *priv) +int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv) { int rc = 0; u32 reg_val; @@ -1070,16 +1060,16 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); /* set stop master bit */ - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - reg_val = iwl_read32(priv, CSR_GP_CNTRL); + reg_val = iwl3945_read32(priv, CSR_GP_CNTRL); if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE == (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE)) IWL_DEBUG_INFO("Card in power save, master is already " "stopped\n"); else { - rc = iwl_poll_bit(priv, CSR_RESET, + rc = iwl3945_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (rc < 0) { @@ -1094,47 +1084,47 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv) return rc; } -int iwl_hw_nic_reset(struct iwl_priv *priv) +int iwl3945_hw_nic_reset(struct iwl3945_priv *priv) { int rc; unsigned long flags; - iwl_hw_nic_stop_master(priv); + iwl3945_hw_nic_stop_master(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - rc = iwl_poll_bit(priv, CSR_GP_CNTRL, + rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (!rc) { - iwl_write_restricted_reg(priv, APMG_CLK_CTRL_REG, + iwl3945_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_BSM_CLK_RQT); udelay(10); - iwl_set_bit(priv, CSR_GP_CNTRL, + iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - iwl_write_restricted_reg(priv, APMG_RTC_INT_MSK_REG, 0x0); - iwl_write_restricted_reg(priv, APMG_RTC_INT_STT_REG, + iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0); + iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG, 0xFFFFFFFF); /* enable DMA */ - iwl_write_restricted_reg(priv, APMG_CLK_EN_REG, + iwl3945_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); udelay(10); - iwl_set_bits_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); - iwl_clear_bits_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } /* Clear the 'host command active' bit... */ @@ -1147,41 +1137,43 @@ int iwl_hw_nic_reset(struct iwl_priv *priv) } /** - * iwl_hw_reg_adjust_power_by_temp - return index delta into power gain settings table - */ -static int iwl_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) + * iwl3945_hw_reg_adjust_power_by_temp + * return index delta into power gain settings table +*/ +static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading) { return (new_reading - old_reading) * (-11) / 100; } /** - * iwl_hw_reg_temp_out_of_range - Keep temperature in sane range + * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range */ -static inline int iwl_hw_reg_temp_out_of_range(int temperature) +static inline int iwl3945_hw_reg_temp_out_of_range(int temperature) { return (((temperature < -260) || (temperature > 25)) ? 1 : 0); } -int iwl_hw_get_temperature(struct iwl_priv *priv) +int iwl3945_hw_get_temperature(struct iwl3945_priv *priv) { - return iwl_read32(priv, CSR_UCODE_DRV_GP2); + return iwl3945_read32(priv, CSR_UCODE_DRV_GP2); } /** - * iwl_hw_reg_txpower_get_temperature - get current temperature by reading from NIC - */ -static int iwl_hw_reg_txpower_get_temperature(struct iwl_priv *priv) + * iwl3945_hw_reg_txpower_get_temperature + * get the current temperature by reading from NIC +*/ +static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv) { int temperature; - temperature = iwl_hw_get_temperature(priv); + temperature = iwl3945_hw_get_temperature(priv); /* driver's okay range is -260 to +25. * human readable okay range is 0 to +285 */ IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT); /* handle insane temp reading */ - if (iwl_hw_reg_temp_out_of_range(temperature)) { + if (iwl3945_hw_reg_temp_out_of_range(temperature)) { IWL_ERROR("Error bad temperature value %d\n", temperature); /* if really really hot(?), @@ -1206,11 +1198,11 @@ static int iwl_hw_reg_txpower_get_temperature(struct iwl_priv *priv) * records new temperature in tx_mgr->temperature. * replaces tx_mgr->last_temperature *only* if calib needed * (assumes caller will actually do the calibration!). */ -static int is_temp_calib_needed(struct iwl_priv *priv) +static int is_temp_calib_needed(struct iwl3945_priv *priv) { int temp_diff; - priv->temperature = iwl_hw_reg_txpower_get_temperature(priv); + priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv); temp_diff = priv->temperature - priv->last_temperature; /* get absolute value */ @@ -1242,7 +1234,7 @@ static int is_temp_calib_needed(struct iwl_priv *priv) /* radio and DSP power table, each step is 1/2 dB. * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */ -static struct iwl_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { +static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { { {251, 127}, /* 2.4 GHz, highest power */ {251, 127}, @@ -1403,7 +1395,7 @@ static struct iwl_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = { {3, 120} } /* 5.x GHz, lowest power */ }; -static inline u8 iwl_hw_reg_fix_power_index(int index) +static inline u8 iwl3945_hw_reg_fix_power_index(int index) { if (index < 0) return 0; @@ -1416,17 +1408,17 @@ static inline u8 iwl_hw_reg_fix_power_index(int index) #define REG_RECALIB_PERIOD (60) /** - * iwl_hw_reg_set_scan_power - Set Tx power for scan probe requests + * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests * * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK) * or 6 Mbit (OFDM) rates. */ -static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, +static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index, s32 rate_index, const s8 *clip_pwrs, - struct iwl_channel_info *ch_info, + struct iwl3945_channel_info *ch_info, int band_index) { - struct iwl_scan_power_info *scan_power_info; + struct iwl3945_scan_power_info *scan_power_info; s8 power; u8 power_index; @@ -1462,7 +1454,7 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, * of the table. */ /* don't exceed table bounds for "real" setting */ - power_index = iwl_hw_reg_fix_power_index(power_index); + power_index = iwl3945_hw_reg_fix_power_index(power_index); scan_power_info->power_table_index = power_index; scan_power_info->tpc.tx_gain = @@ -1472,21 +1464,21 @@ static void iwl_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_index, } /** - * iwl_hw_reg_send_txpower - fill in Tx Power command with gain settings + * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings * * Configures power settings for all rates for the current channel, * using values from channel info struct, and send to NIC */ -int iwl_hw_reg_send_txpower(struct iwl_priv *priv) +int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv) { int rate_idx, i; - const struct iwl_channel_info *ch_info = NULL; - struct iwl_txpowertable_cmd txpower = { + const struct iwl3945_channel_info *ch_info = NULL; + struct iwl3945_txpowertable_cmd txpower = { .channel = priv->active_rxon.channel, }; txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1; - ch_info = iwl_get_channel_info(priv, + ch_info = iwl3945_get_channel_info(priv, priv->phymode, le16_to_cpu(priv->active_rxon.channel)); if (!ch_info) { @@ -1508,7 +1500,7 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv) rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) { txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl_rates[rate_idx].plcp; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n", le16_to_cpu(txpower.channel), @@ -1521,7 +1513,7 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv) for (rate_idx = IWL_FIRST_CCK_RATE; rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) { txpower.power[i].tpc = ch_info->power_info[i].tpc; - txpower.power[i].rate = iwl_rates[rate_idx].plcp; + txpower.power[i].rate = iwl3945_rates[rate_idx].plcp; IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n", le16_to_cpu(txpower.channel), @@ -1531,13 +1523,13 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv) txpower.power[i].rate); } - return iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, - sizeof(struct iwl_txpowertable_cmd), &txpower); + return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, + sizeof(struct iwl3945_txpowertable_cmd), &txpower); } /** - * iwl_hw_reg_set_new_power - Configures power tables at new levels + * iwl3945_hw_reg_set_new_power - Configures power tables at new levels * @ch_info: Channel to update. Uses power_info.requested_power. * * Replace requested_power and base_power_index ch_info fields for @@ -1552,10 +1544,10 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv) * properly fill out the scan powers, and actual h/w gain settings, * and send changes to NIC */ -static int iwl_hw_reg_set_new_power(struct iwl_priv *priv, - struct iwl_channel_info *ch_info) +static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv, + struct iwl3945_channel_info *ch_info) { - struct iwl_channel_power_info *power_info; + struct iwl3945_channel_power_info *power_info; int power_changed = 0; int i; const s8 *clip_pwrs; @@ -1595,7 +1587,7 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv, ch_info->power_info[IWL_RATE_12M_INDEX_TABLE]. requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF; - /* do all CCK rates' iwl_channel_power_info structures */ + /* do all CCK rates' iwl3945_channel_power_info structures */ for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) { power_info->requested_power = power; power_info->base_power_index = @@ -1609,13 +1601,13 @@ static int iwl_hw_reg_set_new_power(struct iwl_priv *priv, } /** - * iwl_hw_reg_get_ch_txpower_limit - returns new power limit for channel + * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel * * NOTE: Returned power limit may be less (but not more) than requested, * based strictly on regulatory (eeprom and spectrum mgt) limitations * (no consideration for h/w clipping limitations). */ -static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) +static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info) { s8 max_power; @@ -1634,7 +1626,7 @@ static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) } /** - * iwl_hw_reg_comp_txpower_temp - Compensate for temperature + * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature * * Compensate txpower settings of *all* channels for temperature. * This only accounts for the difference between current temperature @@ -1643,9 +1635,9 @@ static int iwl_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info) * * If RxOn is "associated", this sends the new Txpower to NIC! */ -static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv) +static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv) { - struct iwl_channel_info *ch_info = NULL; + struct iwl3945_channel_info *ch_info = NULL; int delta_index; const s8 *clip_pwrs; /* array of h/w max power levels for each rate */ u8 a_band; @@ -1666,7 +1658,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv) /* get power index adjustment based on curr and factory * temps */ - delta_index = iwl_hw_reg_adjust_power_by_temp(temperature, + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, ref_temp); /* set tx power value for all rates, OFDM and CCK */ @@ -1679,7 +1671,7 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv) power_idx += delta_index; /* stay within table range */ - power_idx = iwl_hw_reg_fix_power_index(power_idx); + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); ch_info->power_info[rate_index]. power_table_index = (u8) power_idx; ch_info->power_info[rate_index].tpc = @@ -1694,19 +1686,19 @@ static int iwl_hw_reg_comp_txpower_temp(struct iwl_priv *priv) scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { s32 actual_index = (scan_tbl_index == 0) ? IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl_hw_reg_set_scan_power(priv, scan_tbl_index, + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, actual_index, clip_pwrs, ch_info, a_band); } } /* send Txpower command for current channel to ucode */ - return iwl_hw_reg_send_txpower(priv); + return iwl3945_hw_reg_send_txpower(priv); } -int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) +int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power) { - struct iwl_channel_info *ch_info; + struct iwl3945_channel_info *ch_info; s8 max_power; u8 a_band; u8 i; @@ -1728,26 +1720,26 @@ int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) /* find minimum power of all user and regulatory constraints * (does not consider h/w clipping limitations) */ - max_power = iwl_hw_reg_get_ch_txpower_limit(ch_info); + max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info); max_power = min(power, max_power); if (max_power != ch_info->curr_txpow) { ch_info->curr_txpow = max_power; /* this considers the h/w clipping limitations */ - iwl_hw_reg_set_new_power(priv, ch_info); + iwl3945_hw_reg_set_new_power(priv, ch_info); } } /* update txpower settings for all channels, * send to NIC if associated. */ is_temp_calib_needed(priv); - iwl_hw_reg_comp_txpower_temp(priv); + iwl3945_hw_reg_comp_txpower_temp(priv); return 0; } /* will add 3945 channel switch cmd handling later */ -int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel) +int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel) { return 0; } @@ -1762,26 +1754,26 @@ int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel) * -- send new set of gain settings to NIC * NOTE: This should continue working, even when we're not associated, * so we can keep our internal table of scan powers current. */ -void iwl3945_reg_txpower_periodic(struct iwl_priv *priv) +void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv) { /* This will kick in the "brute force" - * iwl_hw_reg_comp_txpower_temp() below */ + * iwl3945_hw_reg_comp_txpower_temp() below */ if (!is_temp_calib_needed(priv)) goto reschedule; /* Set up a new set of temp-adjusted TxPowers, send to NIC. * This is based *only* on current temperature, * ignoring any previous power measurements */ - iwl_hw_reg_comp_txpower_temp(priv); + iwl3945_hw_reg_comp_txpower_temp(priv); reschedule: queue_delayed_work(priv->workqueue, &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ); } -void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) +static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, + struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, thermal_periodic.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) @@ -1793,7 +1785,7 @@ void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) } /** - * iwl_hw_reg_get_ch_grp_index - find the channel-group index (0-4) + * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4) * for the channel. * * This function is used when initializing channel-info structs. @@ -1803,10 +1795,10 @@ void iwl3945_bg_reg_txpower_periodic(struct work_struct *work) * on A-band, EEPROM's "group frequency" entries represent the top * channel in each group 1-4. Group 5 All B/G channels are in group 0. */ -static u16 iwl_hw_reg_get_ch_grp_index(struct iwl_priv *priv, - const struct iwl_channel_info *ch_info) +static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv, + const struct iwl3945_channel_info *ch_info) { - struct iwl_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0]; + struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0]; u8 group; u16 group_index = 0; /* based on factory calib frequencies */ u8 grp_channel; @@ -1832,20 +1824,20 @@ static u16 iwl_hw_reg_get_ch_grp_index(struct iwl_priv *priv, } /** - * iwl_hw_reg_get_matched_power_index - Interpolate to get nominal index + * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index * * Interpolate to get nominal (i.e. at factory calibration temperature) index * into radio/DSP gain settings table for requested power. */ -static int iwl_hw_reg_get_matched_power_index(struct iwl_priv *priv, +static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv, s8 requested_power, s32 setting_index, s32 *new_index) { - const struct iwl_eeprom_txpower_group *chnl_grp = NULL; + const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL; s32 index0, index1; s32 power = 2 * requested_power; s32 i; - const struct iwl_eeprom_txpower_sample *samples; + const struct iwl3945_eeprom_txpower_sample *samples; s32 gains0, gains1; s32 res; s32 denominator; @@ -1885,11 +1877,11 @@ static int iwl_hw_reg_get_matched_power_index(struct iwl_priv *priv, return 0; } -static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv) +static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv) { u32 i; s32 rate_index; - const struct iwl_eeprom_txpower_group *group; + const struct iwl3945_eeprom_txpower_group *group; IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n"); @@ -1965,10 +1957,10 @@ static void iwl_hw_reg_init_channel_groups(struct iwl_priv *priv) * * This does *not* write values to NIC, just sets up our internal table. */ -int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) +int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv) { - struct iwl_channel_info *ch_info = NULL; - struct iwl_channel_power_info *pwr_info; + struct iwl3945_channel_info *ch_info = NULL; + struct iwl3945_channel_power_info *pwr_info; int delta_index; u8 rate_index; u8 scan_tbl_index; @@ -1981,10 +1973,10 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) /* save temperature reference, * so we can determine next time to calibrate */ - temperature = iwl_hw_reg_txpower_get_temperature(priv); + temperature = iwl3945_hw_reg_txpower_get_temperature(priv); priv->last_temperature = temperature; - iwl_hw_reg_init_channel_groups(priv); + iwl3945_hw_reg_init_channel_groups(priv); /* initialize Tx power info for each and every channel, 2.4 and 5.x */ for (i = 0, ch_info = priv->channel_info; i < priv->channel_count; @@ -1995,14 +1987,14 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) /* find this channel's channel group (*not* "band") index */ ch_info->group_index = - iwl_hw_reg_get_ch_grp_index(priv, ch_info); + iwl3945_hw_reg_get_ch_grp_index(priv, ch_info); /* Get this chnlgrp's rate->max/clip-powers table */ clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers; /* calculate power index *adjustment* value according to * diff between current temperature and factory temperature */ - delta_index = iwl_hw_reg_adjust_power_by_temp(temperature, + delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature, priv->eeprom.groups[ch_info->group_index]. temperature); @@ -2025,7 +2017,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) /* get base (i.e. at factory-measured temperature) * power table index for this rate's power */ - rc = iwl_hw_reg_get_matched_power_index(priv, pwr, + rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr, ch_info->group_index, &power_idx); if (rc) { @@ -2038,9 +2030,9 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) power_idx += delta_index; /* stay within range of gain table */ - power_idx = iwl_hw_reg_fix_power_index(power_idx); + power_idx = iwl3945_hw_reg_fix_power_index(power_idx); - /* fill 1 OFDM rate's iwl_channel_power_info struct */ + /* fill 1 OFDM rate's iwl3945_channel_power_info struct */ pwr_info->requested_power = pwr; pwr_info->power_table_index = (u8) power_idx; pwr_info->tpc.tx_gain = @@ -2059,11 +2051,11 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) IWL_CCK_FROM_OFDM_INDEX_DIFF; /* stay within table range */ - pwr_index = iwl_hw_reg_fix_power_index(pwr_index); + pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index); gain = power_gain_table[a_band][pwr_index].tx_gain; dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten; - /* fill each CCK rate's iwl_channel_power_info structure + /* fill each CCK rate's iwl3945_channel_power_info structure * NOTE: All CCK-rate Txpwrs are the same for a given chnl! * NOTE: CCK rates start at end of OFDM rates! */ for (rate_index = 0; @@ -2081,7 +2073,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) { s32 actual_index = (scan_tbl_index == 0) ? IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE; - iwl_hw_reg_set_scan_power(priv, scan_tbl_index, + iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index, actual_index, clip_pwrs, ch_info, a_band); } } @@ -2089,66 +2081,66 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv) return 0; } -int iwl_hw_rxq_stop(struct iwl_priv *priv) +int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv) { int rc; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted(priv, FH_RCSR_CONFIG(0), 0); - rc = iwl_poll_restricted_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000); + iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0); + rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000); if (rc < 0) IWL_ERROR("Can't stop Rx DMA.\n"); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) +int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) { int rc; unsigned long flags; int txq_id = txq->q.id; - struct iwl_shared *shared_data = priv->hw_setting.shared_virt; + struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt; shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr); spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted(priv, FH_CBCC_CTRL(txq_id), 0); - iwl_write_restricted(priv, FH_CBCC_BASE(txq_id), 0); + iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0); + iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0); - iwl_write_restricted(priv, FH_TCSR_CONFIG(txq_id), + iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id), ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT | ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF | ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD | ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL | ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); /* fake read to flush all prev. writes */ - iwl_read32(priv, FH_TSSR_CBB_BASE); + iwl3945_read32(priv, FH_TSSR_CBB_BASE); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -int iwl_hw_get_rx_read(struct iwl_priv *priv) +int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv) { - struct iwl_shared *shared_data = priv->hw_setting.shared_virt; + struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt; return le32_to_cpu(shared_data->rx_read_ptr[0]); } @@ -2156,22 +2148,22 @@ int iwl_hw_get_rx_read(struct iwl_priv *priv) /** * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table */ -int iwl3945_init_hw_rate_table(struct iwl_priv *priv) +int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv) { int rc, i, index, prev_index; - struct iwl_rate_scaling_cmd rate_cmd = { + struct iwl3945_rate_scaling_cmd rate_cmd = { .reserved = {0, 0, 0}, }; - struct iwl_rate_scaling_info *table = rate_cmd.table; + struct iwl3945_rate_scaling_info *table = rate_cmd.table; - for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) { - index = iwl_rates[i].table_rs_index; + for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) { + index = iwl3945_rates[i].table_rs_index; table[index].rate_n_flags = - iwl_hw_set_rate_n_flags(iwl_rates[i].plcp, 0); + iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0); table[index].try_cnt = priv->retry_rate; - prev_index = iwl_get_prev_ieee_rate(i); - table[index].next_rate_index = iwl_rates[prev_index].table_rs_index; + prev_index = iwl3945_get_prev_ieee_rate(i); + table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index; } switch (priv->phymode) { @@ -2180,14 +2172,14 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) /* If one of the following CCK rates is used, * have it fall back to the 6M OFDM rate */ for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) - table[i].next_rate_index = iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; /* Don't fall back to CCK rates */ table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE; /* Don't drop out of OFDM rates */ table[IWL_RATE_6M_INDEX_TABLE].next_rate_index = - iwl_rates[IWL_FIRST_OFDM_RATE].table_rs_index; + iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index; break; case MODE_IEEE80211B: @@ -2195,7 +2187,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) /* If an OFDM rate is used, have it fall back to the * 1M CCK rates */ for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++) - table[i].next_rate_index = iwl_rates[IWL_FIRST_CCK_RATE].table_rs_index; + table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index; /* CCK shouldn't fall back to OFDM... */ table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE; @@ -2208,25 +2200,26 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) /* Update the rate scaling for control frame Tx */ rate_cmd.table_id = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), &rate_cmd); if (rc) return rc; /* Update the rate scaling for data frame Tx */ rate_cmd.table_id = 1; - return iwl_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), + return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd), &rate_cmd); } -int iwl_hw_set_hw_setting(struct iwl_priv *priv) +/* Called when initializing driver */ +int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv) { memset((void *)&priv->hw_setting, 0, - sizeof(struct iwl_driver_hw_info)); + sizeof(struct iwl3945_driver_hw_info)); priv->hw_setting.shared_virt = pci_alloc_consistent(priv->pci_dev, - sizeof(struct iwl_shared), + sizeof(struct iwl3945_shared), &priv->hw_setting.shared_phys); if (!priv->hw_setting.shared_virt) { @@ -2236,31 +2229,31 @@ int iwl_hw_set_hw_setting(struct iwl_priv *priv) } priv->hw_setting.ac_queue_count = AC_NUM; - priv->hw_setting.rx_buffer_size = IWL_RX_BUF_SIZE; - priv->hw_setting.tx_cmd_len = sizeof(struct iwl_tx_cmd); + priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE; + priv->hw_setting.max_pkt_size = 2342; + priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd); priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; - priv->hw_setting.cck_flag = 0; priv->hw_setting.max_stations = IWL3945_STATION_COUNT; priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID; return 0; } -unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl_frame *frame, u8 rate) +unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, + struct iwl3945_frame *frame, u8 rate) { - struct iwl_tx_beacon_cmd *tx_beacon_cmd; + struct iwl3945_tx_beacon_cmd *tx_beacon_cmd; unsigned int frame_size; - tx_beacon_cmd = (struct iwl_tx_beacon_cmd *)&frame->u; + 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 = IWL3945_BROADCAST_ID; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - frame_size = iwl_fill_beacon_frame(priv, + frame_size = iwl3945_fill_beacon_frame(priv, tx_beacon_cmd->frame, - BROADCAST_ADDR, + iwl3945_broadcast_addr, sizeof(frame->u) - sizeof(*tx_beacon_cmd)); BUG_ON(frame_size > MAX_MPDU_SIZE); @@ -2277,35 +2270,43 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, tx_beacon_cmd->tx.supp_rates[1] = (IWL_CCK_BASIC_RATES_MASK & 0xF); - return (sizeof(struct iwl_tx_beacon_cmd) + frame_size); + return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size); } -void iwl_hw_rx_handler_setup(struct iwl_priv *priv) +void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) { priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; } -void iwl_hw_setup_deferred_work(struct iwl_priv *priv) +void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv) { INIT_DELAYED_WORK(&priv->thermal_periodic, iwl3945_bg_reg_txpower_periodic); } -void iwl_hw_cancel_deferred_work(struct iwl_priv *priv) +void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv) { cancel_delayed_work(&priv->thermal_periodic); } -struct pci_device_id iwl_hw_card_ids[] = { - {0x8086, 0x4222, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x4227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +struct pci_device_id iwl3945_hw_card_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4222)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4227)}, {0} }; -inline int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv) +/* + * Clear the OWNER_MSK, to establish driver (instead of uCode running on + * embedded controller) as EEPROM reader; each read 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 some ownership mechanism. Here, the driver + * simply claims ownership, which should be safe when this function is called + * (i.e. before loading uCode!). + */ +inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv) { - _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); + _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK); return 0; } -MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 813902e..709203a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -23,19 +23,991 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ +/* + * Please use this file (iwl-3945.h) for driver implementation definitions. + * Please use iwl-3945-commands.h for uCode API definitions. + * Please use iwl-3945-hw.h for hardware-related definitions. + */ #ifndef __iwl_3945_h__ #define __iwl_3945_h__ +#include /* for struct pci_device_id */ +#include +#include + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +extern struct pci_device_id iwl3945_hw_card_ids[]; + +#define DRV_NAME "iwl3945" +#include "iwl-3945-hw.h" +#include "iwl-prph.h" +#include "iwl-3945-debug.h" + +/* Default noise level to report when noise measurement is not available. + * This may be because we're: + * 1) Not associated (4965, no beacon statistics being sent to driver) + * 2) Scanning (noise measurement does not apply to associated channel) + * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) + * Use default noise value of -127 ... this is below the range of measurable + * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. + * Also, -127 works better than 0 when averaging frames with/without + * noise info (e.g. averaging might be done in app); measured dBm values are + * always negative ... using a negative value as the default keeps all + * averages within an s8's (used in some apps) range of negative values. */ +#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) + +/* Module parameters accessible from iwl-*.c */ +extern int iwl3945_param_hwcrypto; +extern int iwl3945_param_queues_num; + +enum iwl3945_antenna { + IWL_ANTENNA_DIVERSITY, + IWL_ANTENNA_MAIN, + IWL_ANTENNA_AUX +}; + +/* + * RTS threshold here is total size [2347] minus 4 FCS bytes + * Per spec: + * a value of 0 means RTS on all data/management packets + * a value > max MSDU size means no RTS + * else RTS for data/management frames where MPDU is larger + * than RTS value. + */ +#define IWL_RX_BUF_SIZE 3000U +#define DEFAULT_RTS_THRESHOLD 2347U +#define MIN_RTS_THRESHOLD 0U +#define MAX_RTS_THRESHOLD 2347U +#define MAX_MSDU_SIZE 2304U +#define MAX_MPDU_SIZE 2346U +#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_SHORT_RETRY_LIMIT 7U +#define DEFAULT_LONG_RETRY_LIMIT 4U + +struct iwl3945_rx_mem_buffer { + dma_addr_t dma_addr; + struct sk_buff *skb; + struct list_head list; +}; + +struct iwl3945_rt_rx_hdr { + struct ieee80211_radiotap_header rt_hdr; + __le64 rt_tsf; /* TSF */ + u8 rt_flags; /* radiotap packet flags */ + u8 rt_rate; /* rate in 500kb/s */ + __le16 rt_channelMHz; /* channel in MHz */ + __le16 rt_chbitmask; /* channel bitfield */ + s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ + s8 rt_dbmnoise; + u8 rt_antenna; /* antenna number */ + u8 payload[0]; /* payload... */ +} __attribute__ ((packed)); + +struct iwl3945_rt_tx_hdr { + struct ieee80211_radiotap_header rt_hdr; + u8 rt_rate; /* rate in 500kb/s */ + __le16 rt_channel; /* channel in mHz */ + __le16 rt_chbitmask; /* channel bitfield */ + s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ + u8 rt_antenna; /* antenna number */ + u8 payload[0]; /* payload... */ +} __attribute__ ((packed)); + +/* + * Generic queue structure + * + * Contains common data for Rx and Tx queues + */ +struct iwl3945_queue { + int n_bd; /* number of BDs in this queue */ + int write_ptr; /* 1-st empty entry (index) host_w*/ + int read_ptr; /* last used entry (index) host_r*/ + dma_addr_t dma_addr; /* physical addr for BD's */ + int n_window; /* safe queue window */ + u32 id; + int low_mark; /* low watermark, resume queue if free + * space more than this */ + int high_mark; /* high watermark, stop queue if free + * space less than this */ +} __attribute__ ((packed)); + +#define MAX_NUM_OF_TBS (20) + +/* One for each TFD */ +struct iwl3945_tx_info { + struct ieee80211_tx_status status; + struct sk_buff *skb[MAX_NUM_OF_TBS]; +}; + +/** + * struct iwl3945_tx_queue - Tx Queue for DMA + * @q: generic Rx/Tx queue descriptor + * @bd: base of circular buffer of TFDs + * @cmd: array of command/Tx buffers + * @dma_addr_cmd: physical address of cmd/tx buffer array + * @txb: array of per-TFD driver data + * @need_update: indicates need to update read/write index + * + * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame + * descriptors) and required locking structures. + */ +struct iwl3945_tx_queue { + struct iwl3945_queue q; + struct iwl3945_tfd_frame *bd; + struct iwl3945_cmd *cmd; + dma_addr_t dma_addr_cmd; + struct iwl3945_tx_info *txb; + int need_update; + int active; +}; + +#define IWL_NUM_SCAN_RATES (2) + +struct iwl3945_channel_tgd_info { + u8 type; + s8 max_power; +}; + +struct iwl3945_channel_tgh_info { + s64 last_radar_time; +}; + +/* current Tx power values to use, one for each rate for each channel. + * requested power is limited by: + * -- regulatory EEPROM limits for this channel + * -- hardware capabilities (clip-powers) + * -- spectrum management + * -- user preference (e.g. iwconfig) + * when requested power is set, base power index must also be set. */ +struct iwl3945_channel_power_info { + struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 base_power_index; /* gain index for power at factory temp. */ + s8 requested_power; /* power (dBm) requested for this chnl/rate */ +}; + +/* current scan Tx power values to use, one for each scan rate for each + * channel. */ +struct iwl3945_scan_power_info { + struct iwl3945_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ +}; + +/* + * One for each channel, holds all channel setup data + * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant + * with one another! + */ +#define IWL4965_MAX_RATE (33) + +struct iwl3945_channel_info { + struct iwl3945_channel_tgd_info tgd; + struct iwl3945_channel_tgh_info tgh; + struct iwl3945_eeprom_channel eeprom; /* EEPROM regulatory limit */ + struct iwl3945_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for + * FAT channel */ + + u8 channel; /* channel number */ + u8 flags; /* flags copied from EEPROM */ + s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ + s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ + s8 min_power; /* always 0 */ + s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ + + u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ + u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ + u8 phymode; /* MODE_IEEE80211{A,B,G} */ + + /* Radio/DSP gain settings for each "normal" data Tx rate. + * These include, in addition to RF and DSP gain, a few fields for + * remembering/modifying gain settings (indexes). */ + struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE]; + + /* Radio/DSP gain settings for each scan rate, for directed scans. */ + struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; +}; + +struct iwl3945_clip_group { + /* maximum power level to prevent clipping for each rate, derived by + * us from this band's saturation power in EEPROM */ + const s8 clip_powers[IWL_MAX_RATES]; +}; + +#include "iwl-3945-rs.h" + +#define IWL_TX_FIFO_AC0 0 +#define IWL_TX_FIFO_AC1 1 +#define IWL_TX_FIFO_AC2 2 +#define IWL_TX_FIFO_AC3 3 +#define IWL_TX_FIFO_HCCA_1 5 +#define IWL_TX_FIFO_HCCA_2 6 +#define IWL_TX_FIFO_NONE 7 + +/* Minimum number of queues. MAX_NUM is defined in hw specific files */ +#define IWL_MIN_NUM_QUEUES 4 + +/* Power management (not Tx power) structures */ + +struct iwl3945_power_vec_entry { + struct iwl3945_powertable_cmd cmd; + u8 no_dtim; +}; +#define IWL_POWER_RANGE_0 (0) +#define IWL_POWER_RANGE_1 (1) + +#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */ +#define IWL_POWER_INDEX_3 0x03 +#define IWL_POWER_INDEX_5 0x05 +#define IWL_POWER_AC 0x06 +#define IWL_POWER_BATTERY 0x07 +#define IWL_POWER_LIMIT 0x07 +#define IWL_POWER_MASK 0x0F +#define IWL_POWER_ENABLED 0x10 +#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK) + +struct iwl3945_power_mgr { + spinlock_t lock; + struct iwl3945_power_vec_entry pwr_range_0[IWL_POWER_AC]; + struct iwl3945_power_vec_entry pwr_range_1[IWL_POWER_AC]; + u8 active_index; + u32 dtim_val; +}; + +#define IEEE80211_DATA_LEN 2304 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +struct iwl3945_frame { + union { + struct ieee80211_hdr frame; + struct iwl3945_tx_beacon_cmd beacon; + u8 raw[IEEE80211_FRAME_LEN]; + u8 cmd[360]; + } u; + struct list_head list; +}; + +#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf) +#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8) +#define SEQ_TO_INDEX(x) (x & 0xff) +#define INDEX_TO_SEQ(x) (x & 0xff) +#define SEQ_HUGE_FRAME (0x4000) +#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000) +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +enum { + /* CMD_SIZE_NORMAL = 0, */ + CMD_SIZE_HUGE = (1 << 0), + /* CMD_SYNC = 0, */ + CMD_ASYNC = (1 << 1), + /* CMD_NO_SKB = 0, */ + CMD_WANT_SKB = (1 << 2), +}; + +struct iwl3945_cmd; +struct iwl3945_priv; + +struct iwl3945_cmd_meta { + struct iwl3945_cmd_meta *source; + union { + struct sk_buff *skb; + int (*callback)(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, struct sk_buff *skb); + } __attribute__ ((packed)) u; + + /* The CMD_SIZE_HUGE flag bit indicates that the command + * structure is stored at the end of the shared queue memory. */ + u32 flags; + +} __attribute__ ((packed)); + +/** + * struct iwl3945_cmd + * + * For allocation of the command and tx queues, this establishes the overall + * size of the largest command we send to uCode, except for a scan command + * (which is relatively huge; space is allocated separately). + */ +struct iwl3945_cmd { + struct iwl3945_cmd_meta meta; + struct iwl3945_cmd_header hdr; + union { + struct iwl3945_addsta_cmd addsta; + struct iwl3945_led_cmd led; + u32 flags; + u8 val8; + u16 val16; + u32 val32; + struct iwl3945_bt_cmd bt; + struct iwl3945_rxon_time_cmd rxon_time; + struct iwl3945_powertable_cmd powertable; + struct iwl3945_qosparam_cmd qosparam; + struct iwl3945_tx_cmd tx; + struct iwl3945_tx_beacon_cmd tx_beacon; + struct iwl3945_rxon_assoc_cmd rxon_assoc; + u8 *indirect; + u8 payload[360]; + } __attribute__ ((packed)) cmd; +} __attribute__ ((packed)); + +struct iwl3945_host_cmd { + u8 id; + u16 len; + struct iwl3945_cmd_meta meta; + const void *data; +}; + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl3945_cmd) - \ + sizeof(struct iwl3945_cmd_meta)) + +/* + * RX related structures and functions + */ +#define RX_FREE_BUFFERS 64 +#define RX_LOW_WATERMARK 8 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/** + * struct iwl3945_rx_queue - Rx queue + * @processed: Internal index to last handled Rx packet + * @read: Shared index to newest available Rx buffer + * @write: Shared index to oldest written Rx packet + * @free_count: Number of pre-allocated buffers in rx_free + * @rx_free: list of free SKBs for use + * @rx_used: List of Rx buffers with no SKB + * @need_update: flag to indicate we need to update read/write index + * + * NOTE: rx_free and rx_used are used as a FIFO for iwl3945_rx_mem_buffers + */ +struct iwl3945_rx_queue { + __le32 *bd; + dma_addr_t dma_addr; + struct iwl3945_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; + struct iwl3945_rx_mem_buffer *queue[RX_QUEUE_SIZE]; + u32 processed; + u32 read; + u32 write; + u32 free_count; + struct list_head rx_free; + struct list_head rx_used; + int need_update; + spinlock_t lock; +}; + +#define IWL_SUPPORTED_RATES_IE_LEN 8 + +#define SCAN_INTERVAL 100 + +#define MAX_A_CHANNELS 252 +#define MIN_A_CHANNELS 7 + +#define MAX_B_CHANNELS 14 +#define MIN_B_CHANNELS 1 + +#define STATUS_HCMD_ACTIVE 0 /* host command in progress */ +#define STATUS_INT_ENABLED 1 +#define STATUS_RF_KILL_HW 2 +#define STATUS_RF_KILL_SW 3 +#define STATUS_INIT 4 +#define STATUS_ALIVE 5 +#define STATUS_READY 6 +#define STATUS_TEMPERATURE 7 +#define STATUS_GEO_CONFIGURED 8 +#define STATUS_EXIT_PENDING 9 +#define STATUS_IN_SUSPEND 10 +#define STATUS_STATISTICS 11 +#define STATUS_SCANNING 12 +#define STATUS_SCAN_ABORTING 13 +#define STATUS_SCAN_HW 14 +#define STATUS_POWER_PMI 15 +#define STATUS_FW_ERROR 16 + +#define MAX_TID_COUNT 9 + +#define IWL_INVALID_RATE 0xFF +#define IWL_INVALID_VALUE -1 + +struct iwl3945_tid_data { + u16 seq_number; +}; + +struct iwl3945_hw_key { + enum ieee80211_key_alg alg; + int keylen; + u8 key[32]; +}; + +union iwl3945_ht_rate_supp { + u16 rates; + struct { + u8 siso_rate; + u8 mimo_rate; + }; +}; + +#ifdef CONFIG_IWL3945_HT +#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) +#define CFG_HT_MPDU_DENSITY_2USEC (0x5) +#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC + +struct sta_ht_info { + u8 is_ht; + u16 rx_mimo_ps_mode; + u16 tx_mimo_ps_mode; + u16 control_channel; + u8 max_amsdu_size; + u8 ampdu_factor; + u8 mpdu_density; + u8 operating_mode; + u8 supported_chan_width; + u8 extension_chan_offset; + u8 is_green_field; + u8 sgf; + u8 supp_rates[16]; + u8 tx_chan_width; + u8 chan_width_cap; +}; +#endif /*CONFIG_IWL3945_HT */ + +#ifdef CONFIG_IWL3945_QOS + +union iwl3945_qos_capabity { + struct { + u8 edca_count:4; /* bit 0-3 */ + u8 q_ack:1; /* bit 4 */ + u8 queue_request:1; /* bit 5 */ + u8 txop_request:1; /* bit 6 */ + u8 reserved:1; /* bit 7 */ + } q_AP; + struct { + u8 acvo_APSD:1; /* bit 0 */ + u8 acvi_APSD:1; /* bit 1 */ + u8 ac_bk_APSD:1; /* bit 2 */ + u8 ac_be_APSD:1; /* bit 3 */ + u8 q_ack:1; /* bit 4 */ + u8 max_len:2; /* bit 5-6 */ + u8 more_data_ack:1; /* bit 7 */ + } q_STA; + u8 val; +}; + +/* QoS structures */ +struct iwl3945_qos_info { + int qos_enable; + int qos_active; + union iwl3945_qos_capabity qos_cap; + struct iwl3945_qosparam_cmd def_qos_parm; +}; +#endif /*CONFIG_IWL3945_QOS */ + +#define STA_PS_STATUS_WAKE 0 +#define STA_PS_STATUS_SLEEP 1 + +struct iwl3945_station_entry { + struct iwl3945_addsta_cmd sta; + struct iwl3945_tid_data tid[MAX_TID_COUNT]; + union { + struct { + u8 rate; + u8 flags; + } s; + u16 rate_n_flags; + } current_rate; + u8 used; + u8 ps_status; + struct iwl3945_hw_key keyinfo; +}; + +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + void *v_addr; /* access by driver */ + dma_addr_t p_addr; /* access by card's busmaster DMA */ + u32 len; /* bytes */ +}; + +/* uCode file layout */ +struct iwl3945_ucode { + __le32 ver; /* major/minor/subminor */ + __le32 inst_size; /* bytes of runtime instructions */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of initialization instructions */ + __le32 init_data_size; /* bytes of initialization data */ + __le32 boot_size; /* bytes of bootstrap instructions */ + u8 data[0]; /* data in same order as "size" elements */ +}; + +#define IWL_IBSS_MAC_HASH_SIZE 32 + +struct iwl3945_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +/** + * struct iwl4965_driver_hw_info + * @max_txq_num: Max # Tx queues supported + * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) + * @tx_cmd_len: Size of Tx command (but not including frame itself) + * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) + * @rx_buf_size: + * @max_pkt_size: + * @max_rxq_log: Log-base-2 of max_rxq_size + * @max_stations: + * @bcast_sta_id: + * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status + * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status + */ +struct iwl3945_driver_hw_info { + u16 max_txq_num; + u16 ac_queue_count; + u16 tx_cmd_len; + u16 max_rxq_size; + u32 rx_buf_size; + u32 max_pkt_size; + u16 max_rxq_log; + u8 max_stations; + u8 bcast_sta_id; + void *shared_virt; + dma_addr_t shared_phys; +}; + +#define IWL_RX_HDR(x) ((struct iwl3945_rx_frame_hdr *)(\ + x->u.rx_frame.stats.payload + \ + x->u.rx_frame.stats.phy_count)) +#define IWL_RX_END(x) ((struct iwl3945_rx_frame_end *)(\ + IWL_RX_HDR(x)->payload + \ + le16_to_cpu(IWL_RX_HDR(x)->len))) +#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) +#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) + + +/****************************************************************************** + * + * Functions implemented in iwl-base.c which are forward declared here + * for use by iwl-*.c + * + *****************************************************************************/ +struct iwl3945_addsta_cmd; +extern int iwl3945_send_add_station(struct iwl3945_priv *priv, + struct iwl3945_addsta_cmd *sta, u8 flags); +extern u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *bssid, + int is_ap, u8 flags); +extern int iwl3945_is_network_packet(struct iwl3945_priv *priv, + struct ieee80211_hdr *header); +extern int iwl3945_power_init_handle(struct iwl3945_priv *priv); +extern int iwl3945_eeprom_init(struct iwl3945_priv *priv); +#ifdef CONFIG_IWL3945_DEBUG +extern void iwl3945_report_frame(struct iwl3945_priv *priv, + struct iwl3945_rx_packet *pkt, + struct ieee80211_hdr *header, int group100); +#else +static inline void iwl3945_report_frame(struct iwl3945_priv *priv, + struct iwl3945_rx_packet *pkt, + struct ieee80211_hdr *header, + int group100) {} +#endif +extern void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb, + void *data, short len, + struct ieee80211_rx_status *stats, + u16 phy_flags); +extern int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, + struct ieee80211_hdr *header); +extern int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv); +extern void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, + struct iwl3945_rx_queue *rxq); +extern int iwl3945_calc_db_from_ratio(int sig_ratio); +extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm); +extern int iwl3945_tx_queue_init(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq, int count, u32 id); +extern void iwl3945_rx_replenish(void *data); +extern void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq); +extern int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, + const void *data); +extern int __must_check iwl3945_send_cmd(struct iwl3945_priv *priv, + struct iwl3945_host_cmd *cmd); +extern unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, + struct ieee80211_hdr *hdr, + const u8 *dest, int left); +extern int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, + struct iwl3945_rx_queue *q); +extern int iwl3945_send_statistics_request(struct iwl3945_priv *priv); +extern void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, + u32 decrypt_res, + struct ieee80211_rx_status *stats); +extern const u8 iwl3945_broadcast_addr[ETH_ALEN]; + +/* + * Currently used by iwl-3945-rs... look at restructuring so that it doesn't + * call this... todo... fix that. +*/ +extern u8 iwl3945_sync_station(struct iwl3945_priv *priv, int sta_id, + u16 tx_rate, u8 flags); + +/****************************************************************************** + * + * Functions implemented in iwl-[34]*.c which are forward declared here + * for use by iwl-base.c + * + * NOTE: The implementation of these functions are hardware specific + * which is why they are in the hardware specific files (vs. iwl-base.c) + * + * Naming convention -- + * iwl3945_ <-- Its part of iwlwifi (should be changed to iwl3945_) + * iwl3945_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) + * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) + * iwl3945_bg_ <-- Called from work queue context + * iwl3945_mac_ <-- mac80211 callback + * + ****************************************************************************/ +extern void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv); +extern void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv); +extern void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv); +extern int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv); +extern int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv); +extern int iwl3945_hw_nic_init(struct iwl3945_priv *priv); +extern int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv); +extern void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv); +extern void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv); +extern int iwl3945_hw_nic_reset(struct iwl3945_priv *priv); +extern int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *tfd, + dma_addr_t addr, u16 len); +extern int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq); +extern int iwl3945_hw_get_temperature(struct iwl3945_priv *priv); +extern int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq); +extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv, + struct iwl3945_frame *frame, u8 rate); +extern int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv); +extern void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, + struct ieee80211_tx_control *ctrl, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id); +extern int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv); +extern int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power); +extern void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb); +extern void iwl3945_disable_events(struct iwl3945_priv *priv); +extern int iwl4965_get_temperature(const struct iwl3945_priv *priv); + +/** + * iwl3945_hw_find_station - Find station id for a given BSSID + * @bssid: MAC address of station ID to find + * + * NOTE: This should not be hardware specific but the code has + * not yet been merged into a single common layer for managing the + * station tables. + */ +extern u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *bssid); + +extern int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel); + /* * Forward declare iwl-3945.c functions for iwl-base.c */ -extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv); -extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv); -extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv); -extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv); -extern void iwl3945_bg_reg_txpower_periodic(struct work_struct *work); -extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv); -extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, +extern int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv); +extern __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv); +extern int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv); +extern void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv); +extern int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv); +extern u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags); + + +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT + +enum { + MEASUREMENT_READY = (1 << 0), + MEASUREMENT_ACTIVE = (1 << 1), +}; + +#endif + +struct iwl3945_priv { + + /* ieee device used by generic ieee processing code */ + struct ieee80211_hw *hw; + struct ieee80211_channel *ieee_channels; + struct ieee80211_rate *ieee_rates; + struct ieee80211_conf *cache_conf; + + /* temporary frame storage list */ + struct list_head free_frames; + int frames_count; + + u8 phymode; + int alloc_rxb_skb; + + void (*rx_handlers[REPLY_MAX])(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb); + + const struct ieee80211_hw_mode *modes; + +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT + /* spectrum measurement report caching */ + struct iwl3945_spectrum_notification measure_report; + u8 measurement_status; +#endif + /* ucode beacon time */ + u32 ucode_beacon_time; + + /* we allocate array of iwl3945_channel_info for NIC's valid channels. + * Access via channel # using indirect index array */ + struct iwl3945_channel_info *channel_info; /* channel info array */ + u8 channel_count; /* # of channels */ + + /* each calibration channel group in the EEPROM has a derived + * clip setting for each rate. */ + const struct iwl3945_clip_group clip_groups[5]; + + /* thermal calibration */ + s32 temperature; /* degrees Kelvin */ + s32 last_temperature; + + /* Scan related variables */ + unsigned long last_scan_jiffies; + unsigned long next_scan_jiffies; + unsigned long scan_start; + unsigned long scan_pass_start; + unsigned long scan_start_tsf; + int scan_bands; + int one_direct_scan; + u8 direct_ssid_len; + u8 direct_ssid[IW_ESSID_MAX_SIZE]; + struct iwl3945_scan_cmd *scan; + u8 only_active_channel; + + /* spinlock */ + spinlock_t lock; /* protect general shared data */ + spinlock_t hcmd_lock; /* protect hcmd */ + struct mutex mutex; + + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; + + /* uCode images, save to reload in case of failure */ + struct fw_desc ucode_code; /* runtime inst */ + struct fw_desc ucode_data; /* runtime data original */ + struct fw_desc ucode_data_backup; /* runtime data save/restore */ + struct fw_desc ucode_init; /* initialization inst */ + struct fw_desc ucode_init_data; /* initialization data */ + struct fw_desc ucode_boot; /* bootstrap inst */ + + + struct iwl3945_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 iwl3945_rxon_cmd active_rxon; + struct iwl3945_rxon_cmd staging_rxon; + + int error_recovering; + struct iwl3945_rxon_cmd recovery_rxon; + + /* 1st responses from initialize and runtime uCode images. + * 4965's initialize alive response contains some calibration data. */ + struct iwl3945_init_alive_resp card_alive_init; + struct iwl3945_alive_resp card_alive; + +#ifdef LED + /* LED related variables */ + struct iwl3945_activity_blink activity; + unsigned long led_packets; + int led_state; +#endif + + u16 active_rate; + u16 active_rate_basic; + + u8 call_post_assoc_from_beacon; + u8 assoc_station_added; + /* Rate scaling data */ + s8 data_retry_limit; + u8 retry_rate; + + wait_queue_head_t wait_command_queue; + + int activity_timer_active; + + /* Rx and Tx DMA processing queues */ + struct iwl3945_rx_queue rxq; + struct iwl3945_tx_queue txq[IWL_MAX_NUM_QUEUES]; + + unsigned long status; + u32 config; + + int last_rx_rssi; /* From Rx packet statisitics */ + int last_rx_noise; /* From beacon statistics */ + + struct iwl3945_power_mgr power_data; + + struct iwl3945_notif_statistics statistics; + unsigned long last_statistics_time; + + /* context information */ + u8 essid[IW_ESSID_MAX_SIZE]; + u8 essid_len; + u16 rates_mask; + + u32 power_mode; + u32 antenna; + u8 bssid[ETH_ALEN]; + u16 rts_threshold; + u8 mac_addr[ETH_ALEN]; + + /*station table variables */ + spinlock_t sta_lock; + int num_stations; + struct iwl3945_station_entry stations[IWL_STATION_COUNT]; + + /* Indication if ieee80211_ops->open has been called */ + int is_open; + + u8 mac80211_registered; + int is_abg; + + u32 notif_missed_beacons; + + /* Rx'd packet timing information */ + u32 last_beacon_time; + u64 last_tsf; + + /* Duplicate packet detection */ + u16 last_seq_num; + u16 last_frag_num; + unsigned long last_packet_time; + + /* Hash table for finding stations in IBSS network */ + struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; + + /* eeprom */ + struct iwl3945_eeprom eeprom; + + int iw_mode; + + struct sk_buff *ibss_beacon; + + /* Last Rx'd beacon timestamp */ + u32 timestamp0; + u32 timestamp1; + u16 beacon_int; + struct iwl3945_driver_hw_info hw_setting; + int interface_id; + + /* Current association information needed to configure the + * hardware */ + u16 assoc_id; + u16 assoc_capability; + u8 ps_mode; + +#ifdef CONFIG_IWL3945_QOS + struct iwl3945_qos_info qos_data; +#endif /*CONFIG_IWL3945_QOS */ + + struct workqueue_struct *workqueue; + + struct work_struct up; + struct work_struct restart; + struct work_struct calibrated_work; + struct work_struct scan_completed; + struct work_struct rx_replenish; + struct work_struct rf_kill; + struct work_struct abort_scan; + struct work_struct update_link_led; + struct work_struct auth_work; + struct work_struct report_work; + struct work_struct request_scan; + struct work_struct beacon_update; + + struct tasklet_struct irq_tasklet; + + struct delayed_work init_alive_start; + struct delayed_work alive_start; + struct delayed_work activity_timer; + struct delayed_work thermal_periodic; + struct delayed_work gather_stats; + struct delayed_work scan_check; + struct delayed_work post_associate; + +#define IWL_DEFAULT_TX_POWER 0x0F + s8 user_txpower_limit; + s8 max_channel_txpower_limit; + +#ifdef CONFIG_PM + u32 pm_state[16]; +#endif + +#ifdef CONFIG_IWL3945_DEBUG + /* debugging info */ + u32 framecnt_to_us; + atomic_t restrict_refcnt; +#endif +}; /*iwl3945_priv */ + +static inline int iwl3945_is_associated(struct iwl3945_priv *priv) +{ + return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int is_channel_valid(const struct iwl3945_channel_info *ch_info) +{ + if (ch_info == NULL) + return 0; + return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; +} + +static inline int is_channel_narrow(const struct iwl3945_channel_info *ch_info) +{ + return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0; +} + +static inline int is_channel_radar(const struct iwl3945_channel_info *ch_info) +{ + return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; +} + +static inline u8 is_channel_a_band(const struct iwl3945_channel_info *ch_info) +{ + return ch_info->phymode == MODE_IEEE80211A; +} + +static inline u8 is_channel_bg_band(const struct iwl3945_channel_info *ch_info) +{ + return ((ch_info->phymode == MODE_IEEE80211B) || + (ch_info->phymode == MODE_IEEE80211G)); +} + +static inline int is_channel_passive(const struct iwl3945_channel_info *ch) +{ + return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; +} + +static inline int is_channel_ibss(const struct iwl3945_channel_info *ch) +{ + return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; +} + +extern const struct iwl3945_channel_info *iwl3945_get_channel_info( + const struct iwl3945_priv *priv, int phymode, u16 channel); + +/* Requires full declaration of iwl3945_priv before including */ +#include "iwl-3945-io.h" + #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h new file mode 100644 index 0000000..7988c75 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h @@ -0,0 +1,2562 @@ +/****************************************************************************** + * + * 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) 2005 - 2007 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2007 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. + * + *****************************************************************************/ +/* + * Please use this file (iwl-4965-commands.h) only for uCode API definitions. + * Please use iwl-4965-hw.h for hardware-related definitions. + * Please use iwl-4965.h for driver implementation definitions. + */ + +#ifndef __iwl4965_commands_h__ +#define __iwl4965_commands_h__ + +enum { + REPLY_ALIVE = 0x1, + REPLY_ERROR = 0x2, + + /* RXON and QOS commands */ + REPLY_RXON = 0x10, + REPLY_RXON_ASSOC = 0x11, + REPLY_QOS_PARAM = 0x13, + REPLY_RXON_TIMING = 0x14, + + /* Multi-Station support */ + REPLY_ADD_STA = 0x18, + REPLY_REMOVE_STA = 0x19, /* not used */ + REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ + + /* RX, TX, LEDs */ + REPLY_TX = 0x1c, + REPLY_RATE_SCALE = 0x47, /* 3945 only */ + REPLY_LEDS_CMD = 0x48, + REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ + + /* 802.11h related */ + RADAR_NOTIFICATION = 0x70, /* not used */ + REPLY_QUIET_CMD = 0x71, /* not used */ + REPLY_CHANNEL_SWITCH = 0x72, + CHANNEL_SWITCH_NOTIFICATION = 0x73, + REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, + SPECTRUM_MEASURE_NOTIFICATION = 0x75, + + /* Power Management */ + POWER_TABLE_CMD = 0x77, + PM_SLEEP_NOTIFICATION = 0x7A, + PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, + + /* Scan commands and notifications */ + REPLY_SCAN_CMD = 0x80, + REPLY_SCAN_ABORT_CMD = 0x81, + SCAN_START_NOTIFICATION = 0x82, + SCAN_RESULTS_NOTIFICATION = 0x83, + SCAN_COMPLETE_NOTIFICATION = 0x84, + + /* IBSS/AP commands */ + BEACON_NOTIFICATION = 0x90, + REPLY_TX_BEACON = 0x91, + WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ + + /* Miscellaneous commands */ + QUIET_NOTIFICATION = 0x96, /* not used */ + REPLY_TX_PWR_TABLE_CMD = 0x97, + MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ + + /* Bluetooth device coexistance config command */ + REPLY_BT_CONFIG = 0x9b, + + /* Statistics */ + REPLY_STATISTICS_CMD = 0x9c, + STATISTICS_NOTIFICATION = 0x9d, + + /* RF-KILL commands and notifications */ + REPLY_CARD_STATE_CMD = 0xa0, + CARD_STATE_NOTIFICATION = 0xa1, + + /* Missed beacons notification */ + MISSED_BEACONS_NOTIFICATION = 0xa2, + + REPLY_CT_KILL_CONFIG_CMD = 0xa4, + SENSITIVITY_CMD = 0xa8, + REPLY_PHY_CALIBRATION_CMD = 0xb0, + REPLY_RX_PHY_CMD = 0xc0, + REPLY_RX_MPDU_CMD = 0xc1, + REPLY_4965_RX = 0xc3, + REPLY_COMPRESSED_BA = 0xc5, + REPLY_MAX = 0xff +}; + +/****************************************************************************** + * (0) + * Commonly used structures and definitions: + * Command header, rate_n_flags, txpower + * + *****************************************************************************/ + +/* iwl4965_cmd_header flags value */ +#define IWL_CMD_FAILED_MSK 0x40 + +/** + * struct iwl4965_cmd_header + * + * This header format appears in the beginning of each command sent from the + * driver, and each response/notification received from uCode. + */ +struct iwl4965_cmd_header { + u8 cmd; /* Command ID: REPLY_RXON, etc. */ + u8 flags; /* IWL_CMD_* */ + /* + * The driver sets up the sequence number to values of its chosing. + * uCode does not use this value, but passes it back to the driver + * when sending the response to each driver-originated command, so + * the driver can match the response to the command. Since the values + * don't get used by uCode, the driver may set up an arbitrary format. + * + * There is one exception: uCode sets bit 15 when it originates + * the response/notification, i.e. when the response/notification + * is not a direct response to a command sent by the driver. For + * example, uCode issues REPLY_3945_RX when it sends a received frame + * to the driver; it is not a direct response to any driver command. + * + * The Linux driver uses the following format: + * + * 0:7 index/position within Tx queue + * 8:13 Tx queue selection + * 14:14 driver sets this to indicate command is in the 'huge' + * storage at the end of the command buffers, i.e. scan cmd + * 15:15 uCode sets this in uCode-originated response/notification + */ + __le16 sequence; + + /* command or response/notification data follows immediately */ + u8 data[0]; +} __attribute__ ((packed)); + +/** + * 4965 rate_n_flags bit fields + * + * rate_n_flags format is used in following 4965 commands: + * REPLY_4965_RX (response only) + * REPLY_TX (both command and response) + * REPLY_TX_LINK_QUALITY_CMD + * + * High-throughput (HT) rate format for bits 7:0 (bit 8 must be "1"): + * 2-0: 0) 6 Mbps + * 1) 12 Mbps + * 2) 18 Mbps + * 3) 24 Mbps + * 4) 36 Mbps + * 5) 48 Mbps + * 6) 54 Mbps + * 7) 60 Mbps + * + * 3: 0) Single stream (SISO) + * 1) Dual stream (MIMO) + * + * 5: Value of 0x20 in bits 7:0 indicates 6 Mbps FAT duplicate data + * + * Legacy OFDM rate format for bits 7:0 (bit 8 must be "0", bit 9 "0"): + * 3-0: 0xD) 6 Mbps + * 0xF) 9 Mbps + * 0x5) 12 Mbps + * 0x7) 18 Mbps + * 0x9) 24 Mbps + * 0xB) 36 Mbps + * 0x1) 48 Mbps + * 0x3) 54 Mbps + * + * Legacy CCK rate format for bits 7:0 (bit 8 must be "0", bit 9 "1"): + * 3-0: 10) 1 Mbps + * 20) 2 Mbps + * 55) 5.5 Mbps + * 110) 11 Mbps + */ +#define RATE_MCS_CODE_MSK 0x7 +#define RATE_MCS_MIMO_POS 3 +#define RATE_MCS_MIMO_MSK 0x8 +#define RATE_MCS_HT_DUP_POS 5 +#define RATE_MCS_HT_DUP_MSK 0x20 + +/* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */ +#define RATE_MCS_FLAGS_POS 8 +#define RATE_MCS_HT_POS 8 +#define RATE_MCS_HT_MSK 0x100 + +/* Bit 9: (1) CCK, (0) OFDM. HT (bit 8) must be "0" for this bit to be valid */ +#define RATE_MCS_CCK_POS 9 +#define RATE_MCS_CCK_MSK 0x200 + +/* Bit 10: (1) Use Green Field preamble */ +#define RATE_MCS_GF_POS 10 +#define RATE_MCS_GF_MSK 0x400 + +/* Bit 11: (1) Use 40Mhz FAT chnl width, (0) use 20 MHz legacy chnl width */ +#define RATE_MCS_FAT_POS 11 +#define RATE_MCS_FAT_MSK 0x800 + +/* Bit 12: (1) Duplicate data on both 20MHz chnls. FAT (bit 11) must be set. */ +#define RATE_MCS_DUP_POS 12 +#define RATE_MCS_DUP_MSK 0x1000 + +/* Bit 13: (1) Short guard interval (0.4 usec), (0) normal GI (0.8 usec) */ +#define RATE_MCS_SGI_POS 13 +#define RATE_MCS_SGI_MSK 0x2000 + +/** + * rate_n_flags Tx antenna masks (4965 has 2 transmitters): + * bit14:15 01 B inactive, A active + * 10 B active, A inactive + * 11 Both active + */ +#define RATE_MCS_ANT_A_POS 14 +#define RATE_MCS_ANT_B_POS 15 +#define RATE_MCS_ANT_A_MSK 0x4000 +#define RATE_MCS_ANT_B_MSK 0x8000 +#define RATE_MCS_ANT_AB_MSK 0xc000 + + +/** + * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD + * + * Scan uses only one transmitter, so only one analog/dsp gain pair is needed. + */ +struct iwl4965_tx_power { + u8 tx_gain; /* gain for analog radio */ + u8 dsp_atten; /* gain for DSP */ +} __attribute__ ((packed)); + +#define POWER_TABLE_NUM_ENTRIES 33 +#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 +#define POWER_TABLE_CCK_ENTRY 32 + +/** + * union iwl4965_tx_power_dual_stream + * + * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + * Use __le32 version (struct tx_power_dual_stream) when building command. + * + * Driver provides radio gain and DSP attenuation settings to device in pairs, + * one value for each transmitter chain. The first value is for transmitter A, + * second for transmitter B. + * + * For SISO bit rates, both values in a pair should be identical. + * For MIMO rates, one value may be different from the other, + * in order to balance the Tx output between the two transmitters. + * + * See more details in doc for TXPOWER in iwl-4965-hw.h. + */ +union iwl4965_tx_power_dual_stream { + struct { + u8 radio_tx_gain[2]; + u8 dsp_predis_atten[2]; + } s; + u32 dw; +}; + +/** + * struct tx_power_dual_stream + * + * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + * + * Same format as iwl_tx_power_dual_stream, but __le32 + */ +struct tx_power_dual_stream { + __le32 dw; +} __attribute__ ((packed)); + +/** + * struct iwl4965_tx_power_db + * + * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH + */ +struct iwl4965_tx_power_db { + struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (0a) + * Alive and Error Commands & Responses: + * + *****************************************************************************/ + +#define UCODE_VALID_OK __constant_cpu_to_le32(0x1) +#define INITIALIZE_SUBTYPE (9) + +/* + * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "initialize alive" notification once the initialization + * uCode image has completed its work, and is ready to load the runtime image. + * This is the *first* "alive" notification that the driver will receive after + * rebooting uCode; the "initialize" alive is indicated by subtype field == 9. + * + * See comments documenting "BSM" (bootstrap state machine). + * + * For 4965, this notification contains important calibration data for + * calculating txpower settings: + * + * 1) Power supply voltage indication. The voltage sensor outputs higher + * values for lower voltage, and vice versa. + * + * 2) Temperature measurement parameters, for each of two channel widths + * (20 MHz and 40 MHz) supported by the radios. Temperature sensing + * is done via one of the receiver chains, and channel width influences + * the results. + * + * 3) Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation, + * for each of 5 frequency ranges. + */ +struct iwl4965_init_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* "9" for initialize alive */ + __le16 reserved2; + __le32 log_event_table_ptr; + __le32 error_event_table_ptr; + __le32 timestamp; + __le32 is_valid; + + /* calibration values from "initialize" uCode */ + __le32 voltage; /* signed, higher value is lower voltage */ + __le32 therm_r1[2]; /* signed, 1st for normal, 2nd for FAT channel*/ + __le32 therm_r2[2]; /* signed */ + __le32 therm_r3[2]; /* signed */ + __le32 therm_r4[2]; /* signed */ + __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups, + * 2 Tx chains */ +} __attribute__ ((packed)); + + +/** + * REPLY_ALIVE = 0x1 (response only, not a command) + * + * uCode issues this "alive" notification once the runtime image is ready + * to receive commands from the driver. This is the *second* "alive" + * notification that the driver will receive after rebooting uCode; + * this "alive" is indicated by subtype field != 9. + * + * See comments documenting "BSM" (bootstrap state machine). + * + * This response includes two pointers to structures within the device's + * data SRAM (access via HBUS_TARG_MEM_* regs) that are useful for debugging: + * + * 1) log_event_table_ptr indicates base of the event log. This traces + * a 256-entry history of uCode execution within a circular buffer. + * Its header format is: + * + * __le32 log_size; log capacity (in number of entries) + * __le32 type; (1) timestamp with each entry, (0) no timestamp + * __le32 wraps; # times uCode has wrapped to top of circular buffer + * __le32 write_index; next circular buffer entry that uCode would fill + * + * The header is followed by the circular buffer of log entries. Entries + * with timestamps have the following format: + * + * __le32 event_id; range 0 - 1500 + * __le32 timestamp; low 32 bits of TSF (of network, if associated) + * __le32 data; event_id-specific data value + * + * Entries without timestamps contain only event_id and data. + * + * 2) error_event_table_ptr indicates base of the error log. This contains + * information about any uCode error that occurs. For 4965, the format + * of the error log is: + * + * __le32 valid; (nonzero) valid, (0) log is empty + * __le32 error_id; type of error + * __le32 pc; program counter + * __le32 blink1; branch link + * __le32 blink2; branch link + * __le32 ilink1; interrupt link + * __le32 ilink2; interrupt link + * __le32 data1; error-specific data + * __le32 data2; error-specific data + * __le32 line; source code line of error + * __le32 bcon_time; beacon timer + * __le32 tsf_low; network timestamp function timer + * __le32 tsf_hi; network timestamp function timer + * + * The Linux driver can print both logs to the system log when a uCode error + * occurs. + */ +struct iwl4965_alive_resp { + u8 ucode_minor; + u8 ucode_major; + __le16 reserved1; + u8 sw_rev[8]; + u8 ver_type; + u8 ver_subtype; /* not "9" for runtime alive */ + __le16 reserved2; + __le32 log_event_table_ptr; /* SRAM address for event log */ + __le32 error_event_table_ptr; /* SRAM address for error log */ + __le32 timestamp; + __le32 is_valid; +} __attribute__ ((packed)); + + +union tsf { + u8 byte[8]; + __le16 word[4]; + __le32 dw[2]; +}; + +/* + * REPLY_ERROR = 0x2 (response only, not a command) + */ +struct iwl4965_error_resp { + __le32 error_type; + u8 cmd_id; + u8 reserved1; + __le16 bad_cmd_seq_num; + __le32 error_info; + union tsf timestamp; +} __attribute__ ((packed)); + +/****************************************************************************** + * (1) + * RXON Commands & Responses: + * + *****************************************************************************/ + +/* + * Rx config defines & structure + */ +/* rx_config device types */ +enum { + RXON_DEV_TYPE_AP = 1, + RXON_DEV_TYPE_ESS = 3, + RXON_DEV_TYPE_IBSS = 4, + RXON_DEV_TYPE_SNIFFER = 6, +}; + + +#define RXON_RX_CHAIN_DRIVER_FORCE_MSK __constant_cpu_to_le16(0x1<<0) +#define RXON_RX_CHAIN_VALID_MSK __constant_cpu_to_le16(0x7<<1) +#define RXON_RX_CHAIN_VALID_POS (1) +#define RXON_RX_CHAIN_FORCE_SEL_MSK __constant_cpu_to_le16(0x7<<4) +#define RXON_RX_CHAIN_FORCE_SEL_POS (4) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK __constant_cpu_to_le16(0x7<<7) +#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) +#define RXON_RX_CHAIN_CNT_MSK __constant_cpu_to_le16(0x3<<10) +#define RXON_RX_CHAIN_CNT_POS (10) +#define RXON_RX_CHAIN_MIMO_CNT_MSK __constant_cpu_to_le16(0x3<<12) +#define RXON_RX_CHAIN_MIMO_CNT_POS (12) +#define RXON_RX_CHAIN_MIMO_FORCE_MSK __constant_cpu_to_le16(0x1<<14) +#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) + +/* rx_config flags */ +/* band & modulation selection */ +#define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) +#define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) +/* auto detection enable */ +#define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) +/* TGg protection when tx */ +#define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) +/* cck short slot & preamble */ +#define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) +#define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) +/* antenna selection */ +#define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) +#define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) +#define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) +#define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) +/* radar detection enable */ +#define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) +#define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) +/* rx response to host with 8-byte TSF +* (according to ON_AIR deassertion) */ +#define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) + + +/* HT flags */ +#define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) +#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK __constant_cpu_to_le32(0x1<<22) + +#define RXON_FLG_HT_OPERATING_MODE_POS (23) + +#define RXON_FLG_HT_PROT_MSK __constant_cpu_to_le32(0x1<<23) +#define RXON_FLG_FAT_PROT_MSK __constant_cpu_to_le32(0x2<<23) + +#define RXON_FLG_CHANNEL_MODE_POS (25) +#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3<<25) +#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1<<25) +#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2<<25) + +/* rx_config filter flags */ +/* accept all data frames */ +#define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) +/* pass control & management to host */ +#define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) +/* accept multi-cast */ +#define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) +/* don't decrypt uni-cast frames */ +#define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) +/* don't decrypt multi-cast frames */ +#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) +/* STA is associated */ +#define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) +/* transfer to host non bssid beacons in associated state */ +#define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) + +/** + * REPLY_RXON = 0x10 (command, has simple generic response) + * + * RXON tunes the radio tuner to a service channel, and sets up a number + * of parameters that are used primarily for Rx, but also for Tx operations. + * + * NOTE: When tuning to a new channel, driver must set the + * RXON_FILTER_ASSOC_MSK to 0. This will clear station-dependent + * info within the device, including the station tables, tx retry + * rate tables, and txpower tables. Driver must build a new station + * table and txpower table before transmitting anything on the RXON + * channel. + * + * NOTE: All RXONs wipe clean the internal txpower table. Driver must + * issue a new REPLY_TX_PWR_TABLE_CMD after each REPLY_RXON (0x10), + * regardless of whether RXON_FILTER_ASSOC_MSK is set. + */ +struct iwl4965_rxon_cmd { + u8 node_addr[6]; + __le16 reserved1; + u8 bssid_addr[6]; + __le16 reserved2; + u8 wlap_bssid_addr[6]; + __le16 reserved3; + u8 dev_type; + u8 air_propagation; + __le16 rx_chain; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + __le16 assoc_id; + __le32 flags; + __le32 filter_flags; + __le16 channel; + u8 ofdm_ht_single_stream_basic_rates; + u8 ofdm_ht_dual_stream_basic_rates; +} __attribute__ ((packed)); + +/* + * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) + */ +struct iwl4965_rxon_assoc_cmd { + __le32 flags; + __le32 filter_flags; + u8 ofdm_basic_rates; + u8 cck_basic_rates; + u8 ofdm_ht_single_stream_basic_rates; + u8 ofdm_ht_dual_stream_basic_rates; + __le16 rx_chain_select_flags; + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) + */ +struct iwl4965_rxon_time_cmd { + union tsf timestamp; + __le16 beacon_interval; + __le16 atim_window; + __le32 beacon_init_val; + __le16 listen_interval; + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) + */ +struct iwl4965_channel_switch_cmd { + u8 band; + u8 expect_beacon; + __le16 channel; + __le32 rxon_flags; + __le32 rxon_filter_flags; + __le32 switch_time; + struct iwl4965_tx_power_db tx_power; +} __attribute__ ((packed)); + +/* + * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) + */ +struct iwl4965_csa_notification { + __le16 band; + __le16 channel; + __le32 status; /* 0 - OK, 1 - fail */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (2) + * Quality-of-Service (QOS) Commands & Responses: + * + *****************************************************************************/ + +/** + * struct iwl_ac_qos -- QOS timing params for REPLY_QOS_PARAM + * One for each of 4 EDCA access categories in struct iwl_qosparam_cmd + * + * @cw_min: Contention window, start value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x0f. + * @cw_max: Contention window, max value in numbers of slots. + * Should be a power-of-2, minus 1. Device's default is 0x3f. + * @aifsn: Number of slots in Arbitration Interframe Space (before + * performing random backoff timing prior to Tx). Device default 1. + * @edca_txop: Length of Tx opportunity, in uSecs. Device default is 0. + * + * Device will automatically increase contention window by (2*CW) + 1 for each + * transmission retry. Device uses cw_max as a bit mask, ANDed with new CW + * value, to cap the CW value. + */ +struct iwl4965_ac_qos { + __le16 cw_min; + __le16 cw_max; + u8 aifsn; + u8 reserved1; + __le16 edca_txop; +} __attribute__ ((packed)); + +/* QoS flags defines */ +#define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) +#define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) +#define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) + +/* Number of Access Categories (AC) (EDCA), queues 0..3 */ +#define AC_NUM 4 + +/* + * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) + * + * This command sets up timings for each of the 4 prioritized EDCA Tx FIFOs + * 0: Background, 1: Best Effort, 2: Video, 3: Voice. + */ +struct iwl4965_qosparam_cmd { + __le32 qos_flags; + struct iwl4965_ac_qos ac[AC_NUM]; +} __attribute__ ((packed)); + +/****************************************************************************** + * (3) + * Add/Modify Stations Commands & Responses: + * + *****************************************************************************/ +/* + * Multi station support + */ + +/* Special, dedicated locations within device's station table */ +#define IWL_AP_ID 0 +#define IWL_MULTICAST_ID 1 +#define IWL_STA_ID 2 +#define IWL4965_BROADCAST_ID 31 +#define IWL4965_STATION_COUNT 32 + +#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ +#define IWL_INVALID_STATION 255 + +#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1<<8); +#define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) +#define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) +#define STA_FLG_MAX_AGG_SIZE_POS (19) +#define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) +#define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) +#define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) +#define STA_FLG_AGG_MPDU_DENSITY_POS (23) +#define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23) + +/* Use in mode field. 1: modify existing entry, 0: add new station entry */ +#define STA_CONTROL_MODIFY_MSK 0x01 + +/* key flags __le16*/ +#define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) +#define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) +#define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) +#define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) +#define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) + +#define STA_KEY_FLG_KEYID_POS 8 +#define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) + +/* Flags indicate whether to modify vs. don't change various station params */ +#define STA_MODIFY_KEY_MASK 0x01 +#define STA_MODIFY_TID_DISABLE_TX 0x02 +#define STA_MODIFY_TX_RATE_MSK 0x04 +#define STA_MODIFY_ADDBA_TID_MSK 0x08 +#define STA_MODIFY_DELBA_TID_MSK 0x10 + +/* Receiver address (actually, Rx station's index into station table), + * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */ +#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) + +struct iwl4965_keyinfo { + __le16 key_flags; + u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ + u8 reserved1; + __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ + __le16 reserved2; + u8 key[16]; /* 16-byte unicast decryption key */ +} __attribute__ ((packed)); + +/** + * struct sta_id_modify + * @addr[ETH_ALEN]: station's MAC address + * @sta_id: index of station in uCode's station table + * @modify_mask: STA_MODIFY_*, 1: modify, 0: don't change + * + * Driver selects unused table index when adding new station, + * or the index to a pre-existing station entry when modifying that station. + * Some indexes have special purposes (IWL_AP_ID, index 0, is for AP). + * + * modify_mask flags select which parameters to modify vs. leave alone. + */ +struct sta_id_modify { + u8 addr[ETH_ALEN]; + __le16 reserved1; + u8 sta_id; + u8 modify_mask; + __le16 reserved2; +} __attribute__ ((packed)); + +/* + * REPLY_ADD_STA = 0x18 (command) + * + * 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, + * 3945 uses REPLY_RATE_SCALE to set up rate tables). + * + * REPLY_ADD_STA sets up the table entry for one station, either creating + * a new entry, or modifying a pre-existing one. + * + * NOTE: RXON command (without "associated" bit set) wipes the station table + * clean. Moving into RF_KILL state does this also. Driver must set up + * new station table before transmitting anything on the RXON channel + * (except active scans or active measurements; those commands carry + * their own txpower/rate setup data). + * + * When getting started on a new channel, driver must set up the + * IWL_BROADCAST_ID entry (last entry in the table). For a client + * station in a BSS, once an AP is selected, driver sets up the AP STA + * in the IWL_AP_ID entry (1st entry in the table). BROADCAST and AP + * are all that are needed for a BSS client station. If the device is + * used as AP, or in an IBSS network, driver must set up station table + * entries for all STAs in network, starting with index IWL_STA_ID. + */ +struct iwl4965_addsta_cmd { + u8 mode; /* 1: modify existing, 0: add new station */ + u8 reserved[3]; + struct sta_id_modify sta; + struct iwl4965_keyinfo key; + __le32 station_flags; /* STA_FLG_* */ + __le32 station_flags_msk; /* STA_FLG_* */ + + /* bit field to disable (1) or enable (0) Tx for Traffic ID (TID) + * corresponding to bit (e.g. bit 5 controls TID 5). + * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ + __le16 tid_disable_tx; + + __le16 reserved1; + + /* TID for which to add block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + u8 add_immediate_ba_tid; + + /* TID for which to remove block-ack support. + * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */ + u8 remove_immediate_ba_tid; + + /* Starting Sequence Number for added block-ack support. + * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ + __le16 add_immediate_ba_ssn; + + __le32 reserved2; +} __attribute__ ((packed)); + +#define ADD_STA_SUCCESS_MSK 0x1 +#define ADD_STA_NO_ROOM_IN_TABLE 0x2 +#define ADD_STA_NO_BLOCK_ACK_RESOURCE 0x4 +#define ADD_STA_MODIFY_NON_EXIST_STA 0x8 +/* + * REPLY_ADD_STA = 0x18 (response) + */ +struct iwl4965_add_sta_resp { + u8 status; /* ADD_STA_* */ +} __attribute__ ((packed)); + + +/****************************************************************************** + * (4) + * Rx Responses: + * + *****************************************************************************/ + +struct iwl4965_rx_frame_stats { + u8 phy_count; + u8 id; + u8 rssi; + u8 agc; + __le16 sig_avg; + __le16 noise_diff; + u8 payload[0]; +} __attribute__ ((packed)); + +struct iwl4965_rx_frame_hdr { + __le16 channel; + __le16 phy_flags; + u8 reserved1; + u8 rate; + __le16 len; + u8 payload[0]; +} __attribute__ ((packed)); + +#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) +#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) + +#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) +#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) +#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) +#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) +#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) + +#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) +#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) +#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) +#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) +#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) + +#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) +#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) +#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) +#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) +#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) + +struct iwl4965_rx_frame_end { + __le32 status; + __le64 timestamp; + __le32 beacon_timestamp; +} __attribute__ ((packed)); + +/* + * REPLY_3945_RX = 0x1b (response only, not a command) + * + * NOTE: DO NOT dereference from casts to this structure + * It is provided only for calculating minimum data set size. + * The actual offsets of the hdr and end are dynamic based on + * stats.phy_count + */ +struct iwl4965_rx_frame { + struct iwl4965_rx_frame_stats stats; + struct iwl4965_rx_frame_hdr hdr; + struct iwl4965_rx_frame_end end; +} __attribute__ ((packed)); + +/* Fixed (non-configurable) rx data from phy */ +#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4) +#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70) +#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ +#define IWL_AGC_DB_POS (7) +struct iwl4965_rx_non_cfg_phy { + __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ + __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ + u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ + u8 pad[0]; +} __attribute__ ((packed)); + +/* + * REPLY_4965_RX = 0xc3 (response only, not a command) + * Used only for legacy (non 11n) frames. + */ +#define RX_RES_PHY_CNT 14 +struct iwl4965_rx_phy_res { + u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ + u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ + u8 stat_id; /* configurable DSP phy data set ID */ + u8 reserved1; + __le64 timestamp; /* TSF at on air rise */ + __le32 beacon_time_stamp; /* beacon at on-air rise */ + __le16 phy_flags; /* general phy flags: band, modulation, ... */ + __le16 channel; /* channel number */ + __le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */ + __le32 reserved2; + __le32 rate_n_flags; /* RATE_MCS_* */ + __le16 byte_count; /* frame's byte-count */ + __le16 reserved3; +} __attribute__ ((packed)); + +struct iwl4965_rx_mpdu_res_start { + __le16 byte_count; + __le16 reserved; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (5) + * Tx Commands & Responses: + * + * Driver must place each REPLY_TX command into one of the prioritized Tx + * queues in host DRAM, shared between driver and device (see comments for + * SCD registers and Tx/Rx Queues). When the device's Tx scheduler and uCode + * are preparing to transmit, the device pulls the Tx command over the PCI + * bus via one of the device's Tx DMA channels, to fill an internal FIFO + * from which data will be transmitted. + * + * 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). + * + * 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). + * + * 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. + *****************************************************************************/ + +/* REPLY_TX Tx flags field */ + +/* 1: Use Request-To-Send protocol before this frame. + * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ +#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) + +/* 1: Transmit Clear-To-Send to self before this frame. + * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. + * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ +#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) + +/* 1: Expect ACK from receiving station + * 0: Don't expect ACK (MAC header's duration field s/b 0) + * Set this for unicast frames, but not broadcast/multicast. */ +#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) + +/* For 4965: + * 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. + * 0: Use Tx rate/MCS from Tx command's rate_n_flags field. + * This rate will be used for all Tx attempts; it will not be scaled. */ +#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) + +/* 1: Expect immediate block-ack. + * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ +#define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) + +/* 1: Frame requires full Tx-Op protection. + * Set this if either RTS or CTS Tx Flag gets set. */ +#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) + +/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. + * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ +#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) +#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) +#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) + +/* 1: Ignore Bluetooth priority for this frame. + * 0: Delay Tx until Bluetooth device is done (normal usage). */ +#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) + +/* 1: uCode overrides sequence control field in MAC header. + * 0: Driver provides sequence control field in MAC header. + * Set this for management frames, non-QOS data frames, non-unicast frames, + * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ +#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) + +/* 1: This frame is non-last MPDU; more fragments are coming. + * 0: Last fragment, or not using fragmentation. */ +#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) + +/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. + * 0: No TSF required in outgoing frame. + * Set this for transmitting beacons and probe responses. */ +#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) + +/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword + * alignment of frame's payload data field. + * 0: No pad + * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 + * field (but not both). Driver must align frame data (i.e. data following + * MAC header) to DWORD boundary. */ +#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) + +/* HCCA-AP - disable duration overwriting. */ +#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) + + +/* + * TX command security control + */ +#define TX_CMD_SEC_WEP 0x01 +#define TX_CMD_SEC_CCM 0x02 +#define TX_CMD_SEC_TKIP 0x03 +#define TX_CMD_SEC_MSK 0x03 +#define TX_CMD_SEC_SHIFT 6 +#define TX_CMD_SEC_KEY128 0x08 + +/* + * 4965 uCode updates these Tx attempt count values in host DRAM. + * Used for managing Tx retries when expecting block-acks. + * Driver should set these fields to 0. + */ +struct iwl4965_dram_scratch { + u8 try_cnt; /* Tx attempts */ + u8 bt_kill_cnt; /* Tx attempts blocked by Bluetooth device */ + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_TX = 0x1c (command) + */ +struct iwl4965_tx_cmd { + /* + * MPDU byte count: + * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size, + * + 8 byte IV for CCM or TKIP (not used for WEP) + * + Data payload + * + 8-byte MIC (not used for CCM/WEP) + * NOTE: Does not include Tx command bytes, post-MAC pad bytes, + * MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i + * Range: 14-2342 bytes. + */ + __le16 len; + + /* + * MPDU or MSDU byte count for next frame. + * Used for fragmentation and bursting, but not 11n aggregation. + * Same as "len", but for next frame. Set to 0 if not applicable. + */ + __le16 next_frame_len; + + __le32 tx_flags; /* TX_CMD_FLG_* */ + + /* 4965's uCode may modify this field of the Tx command (in host DRAM!). + * Driver must also set dram_lsb_ptr and dram_msb_ptr in this cmd. */ + struct iwl4965_dram_scratch scratch; + + /* Rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is cleared. */ + __le32 rate_n_flags; /* RATE_MCS_* */ + + /* Index of destination station in uCode's station table */ + u8 sta_id; + + /* Type of security encryption: CCM or TKIP */ + u8 sec_ctl; /* TX_CMD_SEC_* */ + + /* + * Index into rate table (see REPLY_TX_LINK_QUALITY_CMD) for initial + * Tx attempt, if TX_CMD_FLG_STA_RATE_MSK is set. Normally "0" for + * data frames, this field may be used to selectively reduce initial + * rate (via non-0 value) for special frames (e.g. management), while + * still supporting rate scaling for all frames. + */ + u8 initial_rate_index; + u8 reserved; + u8 key[16]; + __le16 next_frame_flags; + __le16 reserved2; + union { + __le32 life_time; + __le32 attempt; + } stop_time; + + /* Host DRAM physical address pointer to "scratch" in this command. + * Must be dword aligned. "0" in dram_lsb_ptr disables usage. */ + __le32 dram_lsb_ptr; + u8 dram_msb_ptr; + + u8 rts_retry_limit; /*byte 50 */ + u8 data_retry_limit; /*byte 51 */ + u8 tid_tspec; + union { + __le16 pm_frame_timeout; + __le16 attempt_duration; + } timeout; + + /* + * Duration of EDCA burst Tx Opportunity, in 32-usec units. + * Set this if txop time is not specified by HCCA protocol (e.g. by AP). + */ + __le16 driver_txop; + + /* + * MAC header goes here, followed by 2 bytes padding if MAC header + * length is 26 or 30 bytes, followed by payload data + */ + u8 payload[0]; + struct ieee80211_hdr hdr[0]; +} __attribute__ ((packed)); + +/* TX command response is sent after *all* transmission attempts. + * + * NOTES: + * + * TX_STATUS_FAIL_NEXT_FRAG + * + * If the fragment flag in the MAC header for the frame being transmitted + * is set and there is insufficient time to transmit the next frame, the + * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. + * + * TX_STATUS_FIFO_UNDERRUN + * + * Indicates the host did not provide bytes to the FIFO fast enough while + * a TX was in progress. + * + * TX_STATUS_FAIL_MGMNT_ABORT + * + * This status is only possible if the ABORT ON MGMT RX parameter was + * set to true with the TX command. + * + * If the MSB of the status parameter is set then an abort sequence is + * required. This sequence consists of the host activating the TX Abort + * control line, and then waiting for the TX Abort command response. This + * indicates that a the device is no longer in a transmit state, and that the + * command FIFO has been cleared. The host must then deactivate the TX Abort + * control line. Receiving is still allowed in this case. + */ +enum { + TX_STATUS_SUCCESS = 0x01, + TX_STATUS_DIRECT_DONE = 0x02, + TX_STATUS_FAIL_SHORT_LIMIT = 0x82, + TX_STATUS_FAIL_LONG_LIMIT = 0x83, + TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, + TX_STATUS_FAIL_MGMNT_ABORT = 0x85, + TX_STATUS_FAIL_NEXT_FRAG = 0x86, + TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, + TX_STATUS_FAIL_DEST_PS = 0x88, + TX_STATUS_FAIL_ABORTED = 0x89, + TX_STATUS_FAIL_BT_RETRY = 0x8a, + TX_STATUS_FAIL_STA_INVALID = 0x8b, + TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, + TX_STATUS_FAIL_TID_DISABLE = 0x8d, + TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, + TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, + TX_STATUS_FAIL_TX_LOCKED = 0x90, + TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, +}; + +#define TX_PACKET_MODE_REGULAR 0x0000 +#define TX_PACKET_MODE_BURST_SEQ 0x0100 +#define TX_PACKET_MODE_BURST_FIRST 0x0200 + +enum { + TX_POWER_PA_NOT_ACTIVE = 0x0, +}; + +enum { + TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ + TX_STATUS_DELAY_MSK = 0x00000040, + TX_STATUS_ABORT_MSK = 0x00000080, + TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ + TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ + TX_RESERVED = 0x00780000, /* bits 19:22 */ + TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ + TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ +}; + +/* ******************************* + * TX aggregation status + ******************************* */ + +enum { + AGG_TX_STATE_TRANSMITTED = 0x00, + AGG_TX_STATE_UNDERRUN_MSK = 0x01, + AGG_TX_STATE_BT_PRIO_MSK = 0x02, + AGG_TX_STATE_FEW_BYTES_MSK = 0x04, + AGG_TX_STATE_ABORT_MSK = 0x08, + AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10, + AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20, + AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40, + AGG_TX_STATE_SCD_QUERY_MSK = 0x80, + AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100, + AGG_TX_STATE_RESPONSE_MSK = 0x1ff, + AGG_TX_STATE_DUMP_TX_MSK = 0x200, + AGG_TX_STATE_DELAY_TX_MSK = 0x400 +}; + +#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) + +/* # tx attempts for first frame in aggregation */ +#define AGG_TX_STATE_TRY_CNT_POS 12 +#define AGG_TX_STATE_TRY_CNT_MSK 0xf000 + +/* Command ID and sequence number of Tx command for this frame */ +#define AGG_TX_STATE_SEQ_NUM_POS 16 +#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 + +/* + * REPLY_TX = 0x1c (response) + * + * This response may be in one of two slightly different formats, indicated + * by the frame_count field: + * + * 1) No aggregation (frame_count == 1). This reports Tx results for + * a single frame. Multiple attempts, at various bit rates, may have + * been made for this frame. + * + * 2) Aggregation (frame_count > 1). This reports Tx results for + * 2 or more frames that used block-acknowledge. All frames were + * transmitted at same rate. Rate scaling may have been used if first + * 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. + * This status relates to reasons the tx might have been blocked or aborted + * within the sending station (this 4965), rather than whether it was + * received successfully by the destination station. + */ +struct iwl4965_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 */ + u8 failure_frame; /* # failures due to no ACK (unused for agg) */ + + /* For non-agg: Rate at which frame was successful. + * For agg: Rate at which all frames were transmitted. */ + __le32 rate_n_flags; /* RATE_MCS_* */ + + /* For non-agg: RTS + CTS + frame tx attempts time + ACK. + * For agg: RTS + CTS + aggregation tx time + block-ack time. */ + __le16 wireless_media_time; /* uSecs */ + + __le16 reserved; + __le32 pa_power1; /* RF power amplifier measurement (not used) */ + __le32 pa_power2; + + /* + * For non-agg: frame status TX_STATUS_* + * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status + * fields follow this one, up to frame_count. + * Bit fields: + * 11- 0: AGG_TX_STATE_* status code + * 15-12: Retry count for 1st frame in aggregation (retries + * occur if tx failed for this frame when it was a + * member of a previous aggregation block). If rate + * scaling is used, retry count indicates the rate + * table entry used for all frames in the new agg. + * 31-16: Sequence # for this frame's Tx cmd (not SSN!) + */ + __le32 status; /* TX status (for aggregation status of 1st frame) */ +} __attribute__ ((packed)); + +/* + * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) + * + * Reports Block-Acknowledge from recipient station + */ +struct iwl4965_compressed_ba_resp { + __le32 sta_addr_lo32; + __le16 sta_addr_hi16; + __le16 reserved; + + /* Index of recipient (BA-sending) station in uCode's station table */ + u8 sta_id; + u8 tid; + __le16 ba_seq_ctl; + __le32 ba_bitmap0; + __le32 ba_bitmap1; + __le16 scd_flow; + __le16 scd_ssn; +} __attribute__ ((packed)); + +/* + * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) + * + * See details under "TXPOWER" in iwl-4965-hw.h. + */ +struct iwl4965_txpowertable_cmd { + u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ + u8 reserved; + __le16 channel; + struct iwl4965_tx_power_db tx_power; +} __attribute__ ((packed)); + +/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ +#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1<<0) + +/* # of EDCA prioritized tx fifos */ +#define LINK_QUAL_AC_NUM AC_NUM + +/* # entries in rate scale table to support Tx retries */ +#define LINK_QUAL_MAX_RETRY_NUM 16 + +/* Tx antenna selection values */ +#define LINK_QUAL_ANT_A_MSK (1<<0) +#define LINK_QUAL_ANT_B_MSK (1<<1) +#define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) + + +/** + * struct iwl4965_link_qual_general_params + * + * Used in REPLY_TX_LINK_QUALITY_CMD + */ +struct iwl4965_link_qual_general_params { + u8 flags; + + /* No entries at or above this (driver chosen) index contain MIMO */ + u8 mimo_delimiter; + + /* Best single antenna to use for single stream (legacy, SISO). */ + u8 single_stream_ant_msk; /* LINK_QUAL_ANT_* */ + + /* Best antennas to use for MIMO (unused for 4965, assumes both). */ + u8 dual_stream_ant_msk; /* LINK_QUAL_ANT_* */ + + /* + * If driver needs to use different initial rates for different + * EDCA QOS access categories (as implemented by tx fifos 0-3), + * this table will set that up, by indicating the indexes in the + * rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table at which to start. + * Otherwise, driver should set all entries to 0. + * + * Entry usage: + * 0 = Background, 1 = Best Effort (normal), 2 = Video, 3 = Voice + * TX FIFOs above 3 use same value (typically 0) as TX FIFO 3. + */ + u8 start_rate_index[LINK_QUAL_AC_NUM]; +} __attribute__ ((packed)); + +/** + * struct iwl4965_link_qual_agg_params + * + * Used in REPLY_TX_LINK_QUALITY_CMD + */ +struct iwl4965_link_qual_agg_params { + + /* Maximum number of uSec in aggregation. + * Driver should set this to 4000 (4 milliseconds). */ + __le16 agg_time_limit; + + /* + * Number of Tx retries allowed for a frame, before that frame will + * no longer be considered for the start of an aggregation sequence + * (scheduler will then try to tx it as single frame). + * Driver should set this to 3. + */ + u8 agg_dis_start_th; + + /* + * Maximum number of frames in aggregation. + * 0 = no limit (default). 1 = no aggregation. + * Other values = max # frames in aggregation. + */ + u8 agg_frame_cnt_limit; + + __le32 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) + * + * For 4965 only; 3945 uses REPLY_RATE_SCALE. + * + * Each station in the 4965'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. + * + * The rate scaling procedures described below work well. Of course, other + * procedures are possible, and may work better for particular environments. + * + * + * FILLING THE RATE TABLE + * + * Given a particular initial rate and mode, as determined by the rate + * scaling algorithm described below, the Linux driver uses the following + * formula to fill the rs_table[LINK_QUAL_MAX_RETRY_NUM] rate table in the + * Link Quality command: + * + * + * 1) If using High-throughput (HT) (SISO or MIMO) initial rate: + * a) Use this same initial rate for first 3 entries. + * b) Find next lower available rate using same mode (SISO or MIMO), + * use for next 3 entries. If no lower rate available, switch to + * legacy mode (no FAT channel, no MIMO, no short guard interval). + * c) If using MIMO, set command's mimo_delimiter to number of entries + * using MIMO (3 or 6). + * d) After trying 2 HT rates, switch to legacy mode (no FAT channel, + * no MIMO, no short guard interval), at the next lower bit rate + * (e.g. if second HT bit rate was 54, try 48 legacy), and follow + * legacy procedure for remaining table entries. + * + * 2) If using legacy initial rate: + * a) Use the initial rate for only one entry. + * b) For each following entry, reduce the rate to next lower available + * rate, until reaching the lowest available rate. + * c) When reducing rate, also switch antenna selection. + * d) Once lowest available rate is reached, repeat this rate until + * rate table is filled (16 entries), switching antenna each entry. + * + * + * 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. + * + * 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 + * includes a shifting bitmap of success(1)/failure(0), and sums of successful + * and attempted frames, from which the driver can additionally calculate a + * success ratio (success / attempted) and number of failures + * (attempted - success), and control the size of the window (attempted). + * 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 + * match the modulation characteristics of the history set. + * + * When using block-ack (aggregation), all frames are transmitted at the same + * rate, since there is no per-attempt acknowledgement from the destination + * station. The Tx response struct iwl_tx_resp indicates the Tx rate in + * rate_n_flags field. After receiving a block-ack, the driver can update + * history for the entire block all at once. + * + * + * FINDING BEST STARTING RATE: + * + * When working with a selected initial modulation mode (see below), the + * driver attempts to find a best initial rate. The initial rate is the + * first entry in the Link Quality command's rate table. + * + * 1) Calculate actual throughput (success ratio * expected throughput, see + * table below) for current initial rate. Do this only if enough frames + * have been attempted to make the value meaningful: at least 6 failed + * tx attempts, or at least 8 successes. If not enough, don't try rate + * scaling yet. + * + * 2) Find available rates adjacent to current initial rate. Available means: + * a) supported by hardware && + * b) supported by association && + * c) within any constraints selected by user + * + * 3) Gather measured throughputs for adjacent rates. These might not have + * enough history to calculate a throughput. That's okay, we might try + * using one of them anyway! + * + * 4) Try decreasing rate if, for current rate: + * a) success ratio is < 15% || + * b) lower adjacent rate has better measured throughput || + * c) higher adjacent rate has worse throughput, and lower is unmeasured + * + * As a sanity check, if decrease was determined above, leave rate + * unchanged if: + * a) lower rate unavailable + * b) success ratio at current rate > 85% (very good) + * c) current measured throughput is better than expected throughput + * of lower rate (under perfect 100% tx conditions, see table below) + * + * 5) Try increasing rate if, for current rate: + * a) success ratio is < 15% || + * b) both adjacent rates' throughputs are unmeasured (try it!) || + * b) higher adjacent rate has better measured throughput || + * c) lower adjacent rate has worse throughput, and higher is unmeasured + * + * As a sanity check, if increase was determined above, leave rate + * unchanged if: + * a) success ratio at current rate < 70%. This is not particularly + * good performance; higher rate is sure to have poorer success. + * + * 6) Re-evaluate the rate after each tx frame. If working with block- + * acknowledge, history and statistics may be calculated for the entire + * block (including prior history that fits within the history windows), + * before re-evaluation. + * + * FINDING BEST STARTING MODULATION MODE: + * + * After working with a modulation mode for a "while" (and doing rate scaling), + * the driver searches for a new initial mode in an attempt to improve + * throughput. The "while" is measured by numbers of attempted frames: + * + * For legacy mode, search for new mode after: + * 480 successful frames, or 160 failed frames + * For high-throughput modes (SISO or MIMO), search for new mode after: + * 4500 successful frames, or 400 failed frames + * + * Mode switch possibilities are (3 for each mode): + * + * For legacy: + * Change antenna, try SISO (if HT association), try MIMO (if HT association) + * For SISO: + * Change antenna, try MIMO, try shortened guard interval (SGI) + * For MIMO: + * Try SISO antenna A, SISO antenna B, try shortened guard interval (SGI) + * + * When trying a new mode, use the same bit rate as the old/current mode when + * trying antenna switches and shortened guard interval. When switching to + * SISO from MIMO or legacy, or to MIMO from SISO or legacy, use a rate + * for which the expected throughput (under perfect conditions) is about the + * same or slightly better than the actual measured throughput delivered by + * the old/current mode. + * + * Actual throughput can be estimated by multiplying the expected throughput + * by the success ratio (successful / attempted tx frames). Frame size is + * not considered in this calculation; it assumes that frame size will average + * out to be fairly consistent over several samples. The following are + * metric values for expected throughput assuming 100% success ratio. + * Only G band has support for CCK rates: + * + * RATE: 1 2 5 11 6 9 12 18 24 36 48 54 60 + * + * G: 7 13 35 58 40 57 72 98 121 154 177 186 186 + * A: 0 0 0 0 40 57 72 98 121 154 177 186 186 + * SISO 20MHz: 0 0 0 0 42 42 76 102 124 159 183 193 202 + * SGI SISO 20MHz: 0 0 0 0 46 46 82 110 132 168 192 202 211 + * MIMO 20MHz: 0 0 0 0 74 74 123 155 179 214 236 244 251 + * SGI MIMO 20MHz: 0 0 0 0 81 81 131 164 188 222 243 251 257 + * SISO 40MHz: 0 0 0 0 77 77 127 160 184 220 242 250 257 + * SGI SISO 40MHz: 0 0 0 0 83 83 135 169 193 229 250 257 264 + * MIMO 40MHz: 0 0 0 0 123 123 182 214 235 264 279 285 289 + * SGI MIMO 40MHz: 0 0 0 0 131 131 191 222 242 270 284 289 293 + * + * After the new mode has been tried for a short while (minimum of 6 failed + * frames or 8 successful frames), compare success ratio and actual throughput + * estimate of the new mode with the old. If either is better with the new + * mode, continue to use the new mode. + * + * Continue comparing modes until all 3 possibilities have been tried. + * If moving from legacy to HT, try all 3 possibilities from the new HT + * mode. After trying all 3, a best mode is found. Continue to use this mode + * for the longer "while" described above (e.g. 480 successful frames for + * legacy), and then repeat the search process. + * + */ +struct iwl4965_link_quality_cmd { + + /* Index of destination/recipient station in uCode's station table */ + u8 sta_id; + u8 reserved1; + __le16 control; /* not used */ + struct iwl4965_link_qual_general_params general_params; + struct iwl4965_link_qual_agg_params agg_params; + + /* + * 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. + */ + struct { + __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ + } rs_table[LINK_QUAL_MAX_RETRY_NUM]; + __le32 reserved2; +} __attribute__ ((packed)); + +/* + * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) + */ +struct iwl4965_bt_cmd { + u8 flags; + u8 lead_time; + u8 max_kill; + u8 reserved; + __le32 kill_ack_mask; + __le32 kill_cts_mask; +} __attribute__ ((packed)); + +/****************************************************************************** + * (6) + * Spectrum Management (802.11h) Commands, Responses, Notifications: + * + *****************************************************************************/ + +/* + * Spectrum Management + */ +#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ + RXON_FILTER_CTL2HOST_MSK | \ + RXON_FILTER_ACCEPT_GRP_MSK | \ + RXON_FILTER_DIS_DECRYPT_MSK | \ + RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ + RXON_FILTER_ASSOC_MSK | \ + RXON_FILTER_BCON_AWARE_MSK) + +struct iwl4965_measure_channel { + __le32 duration; /* measurement duration in extended beacon + * format */ + u8 channel; /* channel to measure */ + u8 type; /* see enum iwl4965_measure_type */ + __le16 reserved; +} __attribute__ ((packed)); + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) + */ +struct iwl4965_spectrum_cmd { + __le16 len; /* number of bytes starting from token */ + u8 token; /* token id */ + u8 id; /* measurement id -- 0 or 1 */ + u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ + u8 periodic; /* 1 = periodic */ + __le16 path_loss_timeout; + __le32 start_time; /* start time in extended beacon format */ + __le32 reserved2; + __le32 flags; /* rxon flags */ + __le32 filter_flags; /* rxon filter flags */ + __le16 channel_count; /* minimum 1, maximum 10 */ + __le16 reserved3; + struct iwl4965_measure_channel channels[10]; +} __attribute__ ((packed)); + +/* + * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) + */ +struct iwl4965_spectrum_resp { + u8 token; + u8 id; /* id of the prior command replaced, or 0xff */ + __le16 status; /* 0 - command will be handled + * 1 - cannot handle (conflicts with another + * measurement) */ +} __attribute__ ((packed)); + +enum iwl4965_measurement_state { + IWL_MEASUREMENT_START = 0, + IWL_MEASUREMENT_STOP = 1, +}; + +enum iwl4965_measurement_status { + IWL_MEASUREMENT_OK = 0, + IWL_MEASUREMENT_CONCURRENT = 1, + IWL_MEASUREMENT_CSA_CONFLICT = 2, + IWL_MEASUREMENT_TGH_CONFLICT = 3, + /* 4-5 reserved */ + IWL_MEASUREMENT_STOPPED = 6, + IWL_MEASUREMENT_TIMEOUT = 7, + IWL_MEASUREMENT_PERIODIC_FAILED = 8, +}; + +#define NUM_ELEMENTS_IN_HISTOGRAM 8 + +struct iwl4965_measurement_histogram { + __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ + __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ +} __attribute__ ((packed)); + +/* clear channel availability counters */ +struct iwl4965_measurement_cca_counters { + __le32 ofdm; + __le32 cck; +} __attribute__ ((packed)); + +enum iwl4965_measure_type { + IWL_MEASURE_BASIC = (1 << 0), + IWL_MEASURE_CHANNEL_LOAD = (1 << 1), + IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), + IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), + IWL_MEASURE_FRAME = (1 << 4), + /* bits 5:6 are reserved */ + IWL_MEASURE_IDLE = (1 << 7), +}; + +/* + * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) + */ +struct iwl4965_spectrum_notification { + u8 id; /* measurement id -- 0 or 1 */ + u8 token; + u8 channel_index; /* index in measurement channel list */ + u8 state; /* 0 - start, 1 - stop */ + __le32 start_time; /* lower 32-bits of TSF */ + u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ + u8 channel; + u8 type; /* see enum iwl4965_measurement_type */ + u8 reserved1; + /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only + * valid if applicable for measurement type requested. */ + __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ + __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ + __le32 cca_time; /* channel load time in usecs */ + u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - + * unidentified */ + u8 reserved2[3]; + struct iwl4965_measurement_histogram histogram; + __le32 stop_time; /* lower 32-bits of TSF */ + __le32 status; /* see iwl4965_measurement_status */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (7) + * Power Management Commands, Responses, Notifications: + * + *****************************************************************************/ + +/** + * struct iwl4965_powertable_cmd - Power Table Command + * @flags: See below: + * + * POWER_TABLE_CMD = 0x77 (command, has simple generic response) + * + * PM allow: + * bit 0 - '0' Driver not allow power management + * '1' Driver allow PM (use rest of parameters) + * uCode send sleep notifications: + * bit 1 - '0' Don't send sleep notification + * '1' send sleep notification (SEND_PM_NOTIFICATION) + * Sleep over DTIM + * bit 2 - '0' PM have to walk up every DTIM + * '1' PM could sleep over DTIM till listen Interval. + * PCI power managed + * bit 3 - '0' (PCI_LINK_CTRL & 0x1) + * '1' !(PCI_LINK_CTRL & 0x1) + * Force sleep Modes + * bit 31/30- '00' use both mac/xtal sleeps + * '01' force Mac sleep + * '10' force xtal sleep + * '11' Illegal set + * + * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then + * ucode assume sleep over DTIM is allowed and we don't need to wakeup + * for every DTIM. + */ +#define IWL_POWER_VEC_SIZE 5 + +#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le16(1<<0) +#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le16(1<<2) +#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1<<3) + +struct iwl4965_powertable_cmd { + __le16 flags; + u8 keep_alive_seconds; + u8 debug_flags; + __le32 rx_data_timeout; + __le32 tx_data_timeout; + __le32 sleep_interval[IWL_POWER_VEC_SIZE]; + __le32 keep_alive_beacons; +} __attribute__ ((packed)); + +/* + * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) + * 3945 and 4965 identical. + */ +struct iwl4965_sleep_notification { + u8 pm_sleep_mode; + u8 pm_wakeup_src; + __le16 reserved; + __le32 sleep_time; + __le32 tsf_low; + __le32 bcon_timer; +} __attribute__ ((packed)); + +/* Sleep states. 3945 and 4965 identical. */ +enum { + IWL_PM_NO_SLEEP = 0, + IWL_PM_SLP_MAC = 1, + IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, + IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, + IWL_PM_SLP_PHY = 4, + IWL_PM_SLP_REPENT = 5, + IWL_PM_WAKEUP_BY_TIMER = 6, + IWL_PM_WAKEUP_BY_DRIVER = 7, + IWL_PM_WAKEUP_BY_RFKILL = 8, + /* 3 reserved */ + IWL_PM_NUM_OF_MODES = 12, +}; + +/* + * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) + */ +#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ +#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ +#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ +struct iwl4965_card_state_cmd { + __le32 status; /* CARD_STATE_CMD_* request new power state */ +} __attribute__ ((packed)); + +/* + * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) + */ +struct iwl4965_card_state_notif { + __le32 flags; +} __attribute__ ((packed)); + +#define HW_CARD_DISABLED 0x01 +#define SW_CARD_DISABLED 0x02 +#define RF_CARD_DISABLED 0x04 +#define RXON_CARD_DISABLED 0x10 + +struct iwl4965_ct_kill_config { + __le32 reserved; + __le32 critical_temperature_M; + __le32 critical_temperature_R; +} __attribute__ ((packed)); + +/****************************************************************************** + * (8) + * Scan Commands, Responses, Notifications: + * + *****************************************************************************/ + +struct iwl4965_scan_channel { + /* type is defined as: + * 0:0 active (0 - passive) + * 1:4 SSID direct + * If 1 is set then corresponding SSID IE is transmitted in probe + * 5:7 reserved + */ + u8 type; + u8 channel; + struct iwl4965_tx_power tpc; + __le16 active_dwell; + __le16 passive_dwell; +} __attribute__ ((packed)); + +struct iwl4965_ssid_ie { + u8 id; + u8 len; + u8 ssid[32]; +} __attribute__ ((packed)); + +#define PROBE_OPTION_MAX 0x4 +#define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) +#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) +#define IWL_MAX_SCAN_SIZE 1024 + +/* + * REPLY_SCAN_CMD = 0x80 (command) + */ +struct iwl4965_scan_cmd { + __le16 len; + u8 reserved0; + u8 channel_count; + __le16 quiet_time; /* dwell only this long on quiet chnl + * (active scan) */ + __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ + __le16 good_CRC_th; /* passive -> active promotion threshold */ + __le16 rx_chain; + __le32 max_out_time; /* max usec to be out of associated (service) + * chnl */ + __le32 suspend_time; /* pause scan this long when returning to svc + * chnl. + * 3945 -- 31:24 # beacons, 19:0 additional usec, + * 4965 -- 31:22 # beacons, 21:0 additional usec. + */ + __le32 flags; + __le32 filter_flags; + + struct iwl4965_tx_cmd tx_cmd; + struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX]; + + u8 data[0]; + /* + * The channels start after the probe request payload and are of type: + * + * struct iwl4965_scan_channel channels[0]; + * + * NOTE: Only one band of channels can be scanned per pass. You + * can not mix 2.4GHz channels and 5.2GHz channels and must + * request a scan multiple times (not concurrently) + * + */ +} __attribute__ ((packed)); + +/* Can abort will notify by complete notification with abort status. */ +#define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) +/* complete notification statuses */ +#define ABORT_STATUS 0x2 + +/* + * REPLY_SCAN_CMD = 0x80 (response) + */ +struct iwl4965_scanreq_notification { + __le32 status; /* 1: okay, 2: cannot fulfill request */ +} __attribute__ ((packed)); + +/* + * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) + */ +struct iwl4965_scanstart_notification { + __le32 tsf_low; + __le32 tsf_high; + __le32 beacon_timer; + u8 channel; + u8 band; + u8 reserved[2]; + __le32 status; +} __attribute__ ((packed)); + +#define SCAN_OWNER_STATUS 0x1; +#define MEASURE_OWNER_STATUS 0x2; + +#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ +/* + * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) + */ +struct iwl4965_scanresults_notification { + u8 channel; + u8 band; + u8 reserved[2]; + __le32 tsf_low; + __le32 tsf_high; + __le32 statistics[NUMBER_OF_STATISTICS]; +} __attribute__ ((packed)); + +/* + * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) + */ +struct iwl4965_scancomplete_notification { + u8 scanned_channels; + u8 status; + u8 reserved; + u8 last_channel; + __le32 tsf_low; + __le32 tsf_high; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (9) + * IBSS/AP Commands and Notifications: + * + *****************************************************************************/ + +/* + * BEACON_NOTIFICATION = 0x90 (notification only, not a command) + */ +struct iwl4965_beacon_notif { + struct iwl4965_tx_resp beacon_notify_hdr; + __le32 low_tsf; + __le32 high_tsf; + __le32 ibss_mgr_status; +} __attribute__ ((packed)); + +/* + * REPLY_TX_BEACON = 0x91 (command, has simple generic response) + */ +struct iwl4965_tx_beacon_cmd { + struct iwl4965_tx_cmd tx; + __le16 tim_idx; + u8 tim_size; + u8 reserved1; + struct ieee80211_hdr frame[0]; /* beacon frame */ +} __attribute__ ((packed)); + +/****************************************************************************** + * (10) + * Statistics Commands and Notifications: + * + *****************************************************************************/ + +#define IWL_TEMP_CONVERT 260 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/* Used for passing to driver number of successes and failures per rate */ +struct rate_histogram { + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } success; + union { + __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } failed; +} __attribute__ ((packed)); + +/* statistics command response */ + +struct statistics_rx_phy { + __le32 ina_cnt; + __le32 fina_cnt; + __le32 plcp_err; + __le32 crc32_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 false_alarm_cnt; + __le32 fina_sync_err_cnt; + __le32 sfd_timeout; + __le32 fina_timeout; + __le32 unresponded_rts; + __le32 rxe_frame_limit_overrun; + __le32 sent_ack_cnt; + __le32 sent_cts_cnt; + __le32 sent_ba_rsp_cnt; + __le32 dsp_self_kill; + __le32 mh_format_err; + __le32 re_acq_main_rssi_sum; + __le32 reserved3; +} __attribute__ ((packed)); + +struct statistics_rx_ht_phy { + __le32 plcp_err; + __le32 overrun_err; + __le32 early_overrun_err; + __le32 crc32_good; + __le32 crc32_err; + __le32 mh_format_err; + __le32 agg_crc32_good; + __le32 agg_mpdu_cnt; + __le32 agg_cnt; + __le32 reserved2; +} __attribute__ ((packed)); + +struct statistics_rx_non_phy { + __le32 bogus_cts; /* CTS received when not expecting CTS */ + __le32 bogus_ack; /* ACK received when not expecting ACK */ + __le32 non_bssid_frames; /* number of frames with BSSID that + * doesn't belong to the STA BSSID */ + __le32 filtered_frames; /* count frames that were dumped in the + * filtering process */ + __le32 non_channel_beacons; /* beacons with our bss id but not on + * our serving channel */ + __le32 channel_beacons; /* beacons with our bss id and in our + * serving channel */ + __le32 num_missed_bcon; /* number of missed beacons */ + __le32 adc_rx_saturation_time; /* count in 0.8us units the time the + * ADC was in saturation */ + __le32 ina_detection_search_time;/* total time (in 0.8us) searched + * for INA */ + __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ + __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ + __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ + __le32 interference_data_flag; /* flag for interference data + * availability. 1 when data is + * available. */ + __le32 channel_load; /* counts RX Enable time */ + __le32 dsp_false_alarms; /* DSP false alarm (both OFDM + * and CCK) counter */ + __le32 beacon_rssi_a; + __le32 beacon_rssi_b; + __le32 beacon_rssi_c; + __le32 beacon_energy_a; + __le32 beacon_energy_b; + __le32 beacon_energy_c; +} __attribute__ ((packed)); + +struct statistics_rx { + struct statistics_rx_phy ofdm; + struct statistics_rx_phy cck; + struct statistics_rx_non_phy general; + struct statistics_rx_ht_phy ofdm_ht; +} __attribute__ ((packed)); + +struct statistics_tx_non_phy_agg { + __le32 ba_timeout; + __le32 ba_reschedule_frames; + __le32 scd_query_agg_frame_cnt; + __le32 scd_query_no_agg; + __le32 scd_query_agg; + __le32 scd_query_mismatch; + __le32 frame_not_ready; + __le32 underrun; + __le32 bt_prio_kill; + __le32 rx_ba_rsp_cnt; + __le32 reserved2; + __le32 reserved3; +} __attribute__ ((packed)); + +struct statistics_tx { + __le32 preamble_cnt; + __le32 rx_detected_cnt; + __le32 bt_prio_defer_cnt; + __le32 bt_prio_kill_cnt; + __le32 few_bytes_cnt; + __le32 cts_timeout; + __le32 ack_timeout; + __le32 expected_ack_cnt; + __le32 actual_ack_cnt; + __le32 dump_msdu_cnt; + __le32 burst_abort_next_frame_mismatch_cnt; + __le32 burst_abort_missing_next_frame_cnt; + __le32 cts_timeout_collision; + __le32 ack_or_ba_timeout_collision; + struct statistics_tx_non_phy_agg agg; +} __attribute__ ((packed)); + +struct statistics_dbg { + __le32 burst_check; + __le32 burst_count; + __le32 reserved[4]; +} __attribute__ ((packed)); + +struct statistics_div { + __le32 tx_on_a; + __le32 tx_on_b; + __le32 exec_time; + __le32 probe_time; + __le32 reserved1; + __le32 reserved2; +} __attribute__ ((packed)); + +struct statistics_general { + __le32 temperature; + __le32 temperature_m; + struct statistics_dbg dbg; + __le32 sleep_time; + __le32 slots_out; + __le32 slots_idle; + __le32 ttl_timestamp; + struct statistics_div div; + __le32 rx_enable_counter; + __le32 reserved1; + __le32 reserved2; + __le32 reserved3; +} __attribute__ ((packed)); + +/* + * REPLY_STATISTICS_CMD = 0x9c, + * 3945 and 4965 identical. + * + * This command triggers an immediate response containing uCode statistics. + * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. + * + * If the CLEAR_STATS configuration flag is set, uCode will clear its + * internal copy of the statistics (counters) after issuing the response. + * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). + * + * If the DISABLE_NOTIF configuration flag is set, uCode will not issue + * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag + * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. + */ +#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ +#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ +struct iwl4965_statistics_cmd { + __le32 configuration_flags; /* IWL_STATS_CONF_* */ +} __attribute__ ((packed)); + +/* + * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) + * + * By default, uCode issues this notification after receiving a beacon + * while associated. To disable this behavior, set DISABLE_NOTIF flag in the + * REPLY_STATISTICS_CMD 0x9c, above. + * + * Statistics counters continue to increment beacon after beacon, but are + * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD + * 0x9c with CLEAR_STATS bit set (see above). + * + * uCode also issues this notification during scans. uCode clears statistics + * appropriately so that each notification contains statistics for only the + * one channel that has just been scanned. + */ +#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) +#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) +struct iwl4965_notif_statistics { + __le32 flag; + struct statistics_rx rx; + struct statistics_tx tx; + struct statistics_general general; +} __attribute__ ((packed)); + + +/* + * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) + */ +/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, + * then this notification will be sent. */ +#define CONSECUTIVE_MISSED_BCONS_TH 20 + +struct iwl4965_missed_beacon_notif { + __le32 consequtive_missed_beacons; + __le32 total_missed_becons; + __le32 num_expected_beacons; + __le32 num_recvd_beacons; +} __attribute__ ((packed)); + + +/****************************************************************************** + * (11) + * Rx Calibration Commands: + * + * With the uCode used for open source drivers, most Tx calibration (except + * for Tx Power) and most Rx calibration is done by uCode during the + * "initialize" phase of uCode boot. Driver must calibrate only: + * + * 1) Tx power (depends on temperature), described elsewhere + * 2) Receiver gain balance (optimize MIMO, and detect disconnected antennas) + * 3) Receiver sensitivity (to optimize signal detection) + * + *****************************************************************************/ + +/** + * SENSITIVITY_CMD = 0xa8 (command, has simple generic response) + * + * This command sets up the Rx signal detector for a sensitivity level that + * is high enough to lock onto all signals within the associated network, + * but low enough to ignore signals that are below a certain threshold, so as + * not to have too many "false alarms". False alarms are signals that the + * Rx DSP tries to lock onto, but then discards after determining that they + * are noise. + * + * The optimum number of false alarms is between 5 and 50 per 200 TUs + * (200 * 1024 uSecs, i.e. 204.8 milliseconds) of actual Rx time (i.e. + * time listening, not transmitting). Driver must adjust sensitivity so that + * the ratio of actual false alarms to actual Rx time falls within this range. + * + * While associated, uCode delivers STATISTICS_NOTIFICATIONs after each + * received beacon. These provide information to the driver to analyze the + * sensitivity. Don't analyze statistics that come in from scanning, or any + * other non-associated-network source. Pertinent statistics include: + * + * From "general" statistics (struct statistics_rx_non_phy): + * + * (beacon_energy_[abc] & 0x0FF00) >> 8 (unsigned, higher value is lower level) + * Measure of energy of desired signal. Used for establishing a level + * below which the device does not detect signals. + * + * (beacon_silence_rssi_[abc] & 0x0FF00) >> 8 (unsigned, units in dB) + * Measure of background noise in silent period after beacon. + * + * channel_load + * uSecs of actual Rx time during beacon period (varies according to + * how much time was spent transmitting). + * + * From "cck" and "ofdm" statistics (struct statistics_rx_phy), separately: + * + * false_alarm_cnt + * Signal locks abandoned early (before phy-level header). + * + * plcp_err + * Signal locks abandoned late (during phy-level header). + * + * NOTE: Both false_alarm_cnt and plcp_err increment monotonically from + * beacon to beacon, i.e. each value is an accumulation of all errors + * before and including the latest beacon. Values will wrap around to 0 + * after counting up to 2^32 - 1. Driver must differentiate vs. + * previous beacon's values to determine # false alarms in the current + * beacon period. + * + * Total number of false alarms = false_alarms + plcp_errs + * + * For OFDM, adjust the following table entries in struct iwl_sensitivity_cmd + * (notice that the start points for OFDM are at or close to settings for + * maximum sensitivity): + * + * START / MIN / MAX + * HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX 90 / 85 / 120 + * HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX 170 / 170 / 210 + * HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX 105 / 105 / 140 + * HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX 220 / 220 / 270 + * + * If actual rate of OFDM false alarms (+ plcp_errors) is too high + * (greater than 50 for each 204.8 msecs listening), reduce sensitivity + * by *adding* 1 to all 4 of the table entries above, up to the max for + * each entry. Conversely, if false alarm rate is too low (less than 5 + * for each 204.8 msecs listening), *subtract* 1 from each entry to + * increase sensitivity. + * + * For CCK sensitivity, keep track of the following: + * + * 1). 20-beacon history of maximum background noise, indicated by + * (beacon_silence_rssi_[abc] & 0x0FF00), units in dB, across the + * 3 receivers. For any given beacon, the "silence reference" is + * the maximum of last 60 samples (20 beacons * 3 receivers). + * + * 2). 10-beacon history of strongest signal level, as indicated + * by (beacon_energy_[abc] & 0x0FF00) >> 8, across the 3 receivers, + * i.e. the strength of the signal through the best receiver at the + * moment. These measurements are "upside down", with lower values + * for stronger signals, so max energy will be *minimum* value. + * + * Then for any given beacon, the driver must determine the *weakest* + * of the strongest signals; this is the minimum level that needs to be + * successfully detected, when using the best receiver at the moment. + * "Max cck energy" is the maximum (higher value means lower energy!) + * of the last 10 minima. Once this is determined, driver must add + * a little margin by adding "6" to it. + * + * 3). Number of consecutive beacon periods with too few false alarms. + * Reset this to 0 at the first beacon period that falls within the + * "good" range (5 to 50 false alarms per 204.8 milliseconds rx). + * + * Then, adjust the following CCK table entries in struct iwl_sensitivity_cmd + * (notice that the start points for CCK are at maximum sensitivity): + * + * START / MIN / MAX + * HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX 125 / 125 / 200 + * HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX 200 / 200 / 400 + * HD_MIN_ENERGY_CCK_DET_INDEX 100 / 0 / 100 + * + * If actual rate of CCK false alarms (+ plcp_errors) is too high + * (greater than 50 for each 204.8 msecs listening), method for reducing + * sensitivity is: + * + * 1) *Add* 3 to value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, + * up to max 400. + * + * 2) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is < 160, + * sensitivity has been reduced a significant amount; bring it up to + * a moderate 161. Otherwise, *add* 3, up to max 200. + * + * 3) a) If current value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX is > 160, + * sensitivity has been reduced only a moderate or small amount; + * *subtract* 2 from value in HD_MIN_ENERGY_CCK_DET_INDEX, + * down to min 0. Otherwise (if gain has been significantly reduced), + * don't change the HD_MIN_ENERGY_CCK_DET_INDEX value. + * + * b) Save a snapshot of the "silence reference". + * + * If actual rate of CCK false alarms (+ plcp_errors) is too low + * (less than 5 for each 204.8 msecs listening), method for increasing + * sensitivity is used only if: + * + * 1a) Previous beacon did not have too many false alarms + * 1b) AND difference between previous "silence reference" and current + * "silence reference" (prev - current) is 2 or more, + * OR 2) 100 or more consecutive beacon periods have had rate of + * less than 5 false alarms per 204.8 milliseconds rx time. + * + * Method for increasing sensitivity: + * + * 1) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX, + * down to min 125. + * + * 2) *Subtract* 3 from value in HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX, + * down to min 200. + * + * 3) *Add* 2 to value in HD_MIN_ENERGY_CCK_DET_INDEX, up to max 100. + * + * If actual rate of CCK false alarms (+ plcp_errors) is within good range + * (between 5 and 50 for each 204.8 msecs listening): + * + * 1) Save a snapshot of the silence reference. + * + * 2) If previous beacon had too many CCK false alarms (+ plcp_errors), + * give some extra margin to energy threshold by *subtracting* 8 + * from value in HD_MIN_ENERGY_CCK_DET_INDEX. + * + * For all cases (too few, too many, good range), make sure that the CCK + * detection threshold (energy) is below the energy level for robust + * detection over the past 10 beacon periods, the "Max cck energy". + * Lower values mean higher energy; this means making sure that the value + * in HD_MIN_ENERGY_CCK_DET_INDEX is at or *above* "Max cck energy". + * + * Driver should set the following entries to fixed values: + * + * HD_MIN_ENERGY_OFDM_DET_INDEX 100 + * HD_BARKER_CORR_TH_ADD_MIN_INDEX 190 + * HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX 390 + * HD_OFDM_ENERGY_TH_IN_INDEX 62 + */ + +/* + * Table entries in SENSITIVITY_CMD (struct iwl4965_sensitivity_cmd) + */ +#define HD_TABLE_SIZE (11) /* number of entries */ +#define HD_MIN_ENERGY_CCK_DET_INDEX (0) /* table indexes */ +#define HD_MIN_ENERGY_OFDM_DET_INDEX (1) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) +#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) +#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) +#define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) +#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) +#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) +#define HD_OFDM_ENERGY_TH_IN_INDEX (10) + +/* Control field in struct iwl4965_sensitivity_cmd */ +#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) +#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) + +/** + * struct iwl4965_sensitivity_cmd + * @control: (1) updates working table, (0) updates default table + * @table: energy threshold values, use HD_* as index into table + * + * Always use "1" in "control" to update uCode's working table and DSP. + */ +struct iwl4965_sensitivity_cmd { + __le16 control; /* always use "1" */ + __le16 table[HD_TABLE_SIZE]; /* use HD_* as index */ +} __attribute__ ((packed)); + + +/** + * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) + * + * This command sets the relative gains of 4965'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 + * beacons from the associated network (don't collect statistics that come + * in from scanning, or any other non-network source). + * + * DISCONNECTED ANTENNA: + * + * Driver should determine which antennas are actually connected, by comparing + * average beacon signal levels for the 3 Rx chains. Accumulate (add) the + * following values over 20 beacons, one accumulator for each of the chains + * a/b/c, from struct statistics_rx_non_phy: + * + * beacon_rssi_[abc] & 0x0FF (unsigned, units in dB) + * + * Find the strongest signal from among a/b/c. Compare the other two to the + * strongest. If any signal is more than 15 dB (times 20, unless you + * divide the accumulated values by 20) below the strongest, the driver + * considers that antenna to be disconnected, and should not try to use that + * antenna/chain for Rx or Tx. If both A and B seem to be disconnected, + * driver should declare the stronger one as connected, and attempt to use it + * (A and B are the only 2 Tx chains!). + * + * + * RX BALANCE: + * + * Driver should balance the 3 receivers (but just the ones that are connected + * to antennas, see above) for gain, by comparing the average signal levels + * detected during the silence after each beacon (background noise). + * Accumulate (add) the following values over 20 beacons, one accumulator for + * each of the chains a/b/c, from struct statistics_rx_non_phy: + * + * beacon_silence_rssi_[abc] & 0x0FF (unsigned, units in dB) + * + * Find the weakest background noise level from among a/b/c. This Rx chain + * will be the reference, with 0 gain adjustment. Attenuate other channels by + * finding noise difference: + * + * (accum_noise[i] - accum_noise[reference]) / 30 + * + * The "30" adjusts the dB in the 20 accumulated samples to units of 1.5 dB. + * For use in diff_gain_[abc] fields of struct iwl_calibration_cmd, the + * driver should limit the difference results to a range of 0-3 (0-4.5 dB), + * and set bit 2 to indicate "reduce gain". The value for the reference + * (weakest) chain should be "0". + * + * diff_gain_[abc] bit fields: + * 2: (1) reduce gain, (0) increase gain + * 1-0: amount of gain, units of 1.5 dB + */ + +/* "Differential Gain" opcode used in REPLY_PHY_CALIBRATION_CMD. */ +#define PHY_CALIBRATE_DIFF_GAIN_CMD (7) + +struct iwl4965_calibration_cmd { + u8 opCode; /* PHY_CALIBRATE_DIFF_GAIN_CMD (7) */ + u8 flags; /* not used */ + __le16 reserved; + s8 diff_gain_a; /* see above */ + s8 diff_gain_b; + s8 diff_gain_c; + u8 reserved1; +} __attribute__ ((packed)); + +/****************************************************************************** + * (12) + * Miscellaneous Commands: + * + *****************************************************************************/ + +/* + * LEDs Command & Response + * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) + * + * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), + * this command turns it on or off, or sets up a periodic blinking cycle. + */ +struct iwl4965_led_cmd { + __le32 interval; /* "interval" in uSec */ + u8 id; /* 1: Activity, 2: Link, 3: Tech */ + u8 off; /* # intervals off while blinking; + * "0", with >0 "on" value, turns LED on */ + u8 on; /* # intervals on while blinking; + * "0", regardless of "off", turns LED off */ + u8 reserved; +} __attribute__ ((packed)); + +/****************************************************************************** + * (13) + * Union of all expected notifications/responses: + * + *****************************************************************************/ + +struct iwl4965_rx_packet { + __le32 len; + struct iwl4965_cmd_header hdr; + union { + struct iwl4965_alive_resp alive_frame; + struct iwl4965_rx_frame rx_frame; + struct iwl4965_tx_resp tx_resp; + struct iwl4965_spectrum_notification spectrum_notif; + struct iwl4965_csa_notification csa_notif; + struct iwl4965_error_resp err_resp; + struct iwl4965_card_state_notif card_state_notif; + struct iwl4965_beacon_notif beacon_status; + struct iwl4965_add_sta_resp add_sta; + struct iwl4965_sleep_notification sleep_notif; + struct iwl4965_spectrum_resp spectrum; + struct iwl4965_notif_statistics stats; + struct iwl4965_compressed_ba_resp compressed_ba; + struct iwl4965_missed_beacon_notif missed_beacon; + __le32 status; + u8 raw[0]; + } u; +} __attribute__ ((packed)); + +#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl4965_rx_frame)) + +#endif /* __iwl4965_commands_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-debug.h b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h new file mode 100644 index 0000000..00bc1fa --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-4965-debug.h @@ -0,0 +1,152 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl4965_debug_h__ +#define __iwl4965_debug_h__ + +#ifdef CONFIG_IWL4965_DEBUG +extern u32 iwl4965_debug_level; +#define IWL_DEBUG(level, fmt, args...) \ +do { if (iwl4965_debug_level & (level)) \ + printk(KERN_ERR DRV_NAME": %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) + +#define IWL_DEBUG_LIMIT(level, fmt, args...) \ +do { if ((iwl4965_debug_level & (level)) && net_ratelimit()) \ + printk(KERN_ERR DRV_NAME": %c %s " fmt, \ + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) +#else +static inline void IWL_DEBUG(int level, const char *fmt, ...) +{ +} +static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) +{ +} +#endif /* CONFIG_IWL4965_DEBUG */ + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define IWL_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a IWL_xxxx_DEBUG() macro definition for your + * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/iwl/debug_level + * + * you simply need to add your entry to the iwl4965_debug_levels array. + * + * If you do not see debug_level in /proc/net/iwl then you do not have + * CONFIG_IWL4965_DEBUG defined in your kernel configuration + * + */ + +#define IWL_DL_INFO (1<<0) +#define IWL_DL_MAC80211 (1<<1) +#define IWL_DL_HOST_COMMAND (1<<2) +#define IWL_DL_STATE (1<<3) + +#define IWL_DL_RADIO (1<<7) +#define IWL_DL_POWER (1<<8) +#define IWL_DL_TEMP (1<<9) + +#define IWL_DL_NOTIF (1<<10) +#define IWL_DL_SCAN (1<<11) +#define IWL_DL_ASSOC (1<<12) +#define IWL_DL_DROP (1<<13) + +#define IWL_DL_TXPOWER (1<<14) + +#define IWL_DL_AP (1<<15) + +#define IWL_DL_FW (1<<16) +#define IWL_DL_RF_KILL (1<<17) +#define IWL_DL_FW_ERRORS (1<<18) + +#define IWL_DL_LED (1<<19) + +#define IWL_DL_RATE (1<<20) + +#define IWL_DL_CALIB (1<<21) +#define IWL_DL_WEP (1<<22) +#define IWL_DL_TX (1<<23) +#define IWL_DL_RX (1<<24) +#define IWL_DL_ISR (1<<25) +#define IWL_DL_HT (1<<26) +#define IWL_DL_IO (1<<27) +#define IWL_DL_11H (1<<28) + +#define IWL_DL_STATS (1<<29) +#define IWL_DL_TX_REPLY (1<<30) +#define IWL_DL_QOS (1<<31) + +#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) +#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) +#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) + +#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) +#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) +#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) +#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) +#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) +#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) +#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) +#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) +#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a) +#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) +#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) +#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) +#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) +#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) +#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) +#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) +#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) +#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) +#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ + IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) +#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) +#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) +#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) +#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) +#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) +#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) +#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) + +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 99a19ef..7e7d6e4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -8,7 +8,7 @@ * Copyright(c) 2005 - 2007 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 Geeral Public License as + * 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 @@ -60,48 +60,618 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +/* + * Please use this file (iwl-4965-hw.h) only for hardware-related definitions. + * Use iwl-4965-commands.h for uCode API definitions. + * Use iwl-4965.h for driver implementation definitions. + */ #ifndef __iwl_4965_hw_h__ #define __iwl_4965_hw_h__ -#define IWL_RX_BUF_SIZE (4 * 1024) -#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE +/* + * uCode queue management definitions ... + * Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4. + * The first queue used for block-ack aggregation is #7 (4965 only). + * All block-ack aggregation queues should map to Tx DMA/FIFO channel 7. + */ +#define IWL_CMD_QUEUE_NUM 4 +#define IWL_CMD_FIFO_NUM 4 +#define IWL_BACK_QUEUE_FIRST_ID 7 + +/* Tx rates */ +#define IWL_CCK_RATES 4 +#define IWL_OFDM_RATES 8 +#define IWL_HT_RATES 16 +#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES) + +/* Time constants */ +#define SHORT_SLOT_TIME 9 +#define LONG_SLOT_TIME 20 + +/* RSSI to dBm */ +#define IWL_RSSI_OFFSET 44 + +/* + * EEPROM related constants, enums, and structures. + */ + +/* + * EEPROM access time values: + * + * Driver initiates EEPROM read by writing byte address << 1 to CSR_EEPROM_REG, + * then clearing (with subsequent read/modify/write) CSR_EEPROM_REG bit + * CSR_EEPROM_REG_BIT_CMD (0x2). + * Driver then polls CSR_EEPROM_REG for CSR_EEPROM_REG_READ_VALID_MSK (0x1). + * When polling, wait 10 uSec between polling loops, up to a maximum 5000 uSec. + * Driver reads 16-bit value from bits 31-16 of CSR_EEPROM_REG. + */ +#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ +#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */ + +/* + * Regulatory channel usage flags in EEPROM struct iwl4965_eeprom_channel.flags. + * + * IBSS and/or AP operation is allowed *only* on those channels with + * (VALID && IBSS && ACTIVE && !RADAR). This restriction is in place because + * RADAR detection is not supported by the 4965 driver, but is a + * requirement for establishing a new network for legal operation on channels + * requiring RADAR detection or restricting ACTIVE scanning. + * + * NOTE: "WIDE" flag does not indicate anything about "FAT" 40 MHz channels. + * It only indicates that 20 MHz channel use is supported; FAT channel + * usage is indicated by a separate set of regulatory flags for each + * FAT channel pair. + * + * NOTE: Using a channel inappropriately will result in a uCode error! + */ +enum { + EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ + EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ + /* Bit 2 Reserved */ + EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ + EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ + EEPROM_CHANNEL_WIDE = (1 << 5), /* 20 MHz channel okay */ + EEPROM_CHANNEL_NARROW = (1 << 6), /* 10 MHz channel (not used) */ + EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ +}; + +/* SKU Capabilities */ +#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) +#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) + +/* *regulatory* channel data format in eeprom, one for each channel. + * There are separate entries for FAT (40 MHz) vs. normal (20 MHz) channels. */ +struct iwl4965_eeprom_channel { + u8 flags; /* EEPROM_CHANNEL_* flags copied from EEPROM */ + s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ +} __attribute__ ((packed)); + +/* 4965 has two radio transmitters (and 3 radio receivers) */ +#define EEPROM_TX_POWER_TX_CHAINS (2) + +/* 4965 has room for up to 8 sets of txpower calibration data */ +#define EEPROM_TX_POWER_BANDS (8) + +/* 4965 factory calibration measures txpower gain settings for + * each of 3 target output levels */ +#define EEPROM_TX_POWER_MEASUREMENTS (3) + +/* 4965 driver does not work with txpower calibration version < 5. + * Look for this in calib_version member of struct iwl4965_eeprom. */ +#define EEPROM_TX_POWER_VERSION_NEW (5) + + +/* + * 4965 factory calibration data for one txpower level, on one channel, + * measured on one of the 2 tx chains (radio transmitter and associated + * antenna). EEPROM contains: + * + * 1) Temperature (degrees Celsius) of device when measurement was made. + * + * 2) Gain table index used to achieve the target measurement power. + * This refers to the "well-known" gain tables (see iwl-4965-hw.h). + * + * 3) Actual measured output power, in half-dBm ("34" = 17 dBm). + * + * 4) RF power amplifier detector level measurement (not used). + */ +struct iwl4965_eeprom_calib_measure { + u8 temperature; /* Device temperature (Celsius) */ + u8 gain_idx; /* Index into gain table */ + u8 actual_pow; /* Measured RF output power, half-dBm */ + s8 pa_det; /* Power amp detector level (not used) */ +} __attribute__ ((packed)); + + +/* + * 4965 measurement set for one channel. EEPROM contains: + * + * 1) Channel number measured + * + * 2) Measurements for each of 3 power levels for each of 2 radio transmitters + * (a.k.a. "tx chains") (6 measurements altogether) + */ +struct iwl4965_eeprom_calib_ch_info { + u8 ch_num; + struct iwl4965_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS] + [EEPROM_TX_POWER_MEASUREMENTS]; +} __attribute__ ((packed)); + +/* + * 4965 txpower subband info. + * + * For each frequency subband, EEPROM contains the following: + * + * 1) First and last channels within range of the subband. "0" values + * indicate that this sample set is not being used. + * + * 2) Sample measurement sets for 2 channels close to the range endpoints. + */ +struct iwl4965_eeprom_calib_subband_info { + u8 ch_from; /* channel number of lowest channel in subband */ + u8 ch_to; /* channel number of highest channel in subband */ + struct iwl4965_eeprom_calib_ch_info ch1; + struct iwl4965_eeprom_calib_ch_info ch2; +} __attribute__ ((packed)); + + +/* + * 4965 txpower calibration info. EEPROM contains: + * + * 1) Factory-measured saturation power levels (maximum levels at which + * tx power amplifier can output a signal without too much distortion). + * There is one level for 2.4 GHz band and one for 5 GHz band. These + * values apply to all channels within each of the bands. + * + * 2) Factory-measured power supply voltage level. This is assumed to be + * constant (i.e. same value applies to all channels/bands) while the + * factory measurements are being made. + * + * 3) Up to 8 sets of factory-measured txpower calibration values. + * These are for different frequency ranges, since txpower gain + * characteristics of the analog radio circuitry vary with frequency. + * + * Not all sets need to be filled with data; + * struct iwl4965_eeprom_calib_subband_info contains range of channels + * (0 if unused) for each set of data. + */ +struct iwl4965_eeprom_calib_info { + u8 saturation_power24; /* half-dBm (e.g. "34" = 17 dBm) */ + u8 saturation_power52; /* half-dBm */ + s16 voltage; /* signed */ + struct iwl4965_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS]; +} __attribute__ ((packed)); + + +/* + * 4965 EEPROM map + */ +struct iwl4965_eeprom { + u8 reserved0[16]; +#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ + u16 device_id; /* abs.ofs: 16 */ + u8 reserved1[2]; +#define EEPROM_PMC (2*0x0A) /* 2 bytes */ + u16 pmc; /* abs.ofs: 20 */ + u8 reserved2[20]; +#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ + u8 mac_address[6]; /* abs.ofs: 42 */ + u8 reserved3[58]; +#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ + u16 board_revision; /* abs.ofs: 106 */ + u8 reserved4[11]; +#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ + u8 board_pba_number[9]; /* abs.ofs: 119 */ + u8 reserved5[8]; +#define EEPROM_VERSION (2*0x44) /* 2 bytes */ + u16 version; /* abs.ofs: 136 */ +#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ + u8 sku_cap; /* abs.ofs: 138 */ +#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */ + u8 leds_mode; /* abs.ofs: 139 */ +#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ + u16 oem_mode; +#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ + u16 wowlan_mode; /* abs.ofs: 142 */ +#define EEPROM_LEDS_TIME_INTERVAL (2*0x48) /* 2 bytes */ + u16 leds_time_interval; /* abs.ofs: 144 */ +#define EEPROM_LEDS_OFF_TIME (2*0x49) /* 1 bytes */ + u8 leds_off_time; /* abs.ofs: 146 */ +#define EEPROM_LEDS_ON_TIME (2*0x49+1) /* 1 bytes */ + u8 leds_on_time; /* abs.ofs: 147 */ +#define EEPROM_ALMGOR_M_VERSION (2*0x4A) /* 1 bytes */ + u8 almgor_m_version; /* abs.ofs: 148 */ +#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */ + u8 antenna_switch_type; /* abs.ofs: 149 */ + u8 reserved6[8]; +#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */ + u16 board_revision_4965; /* abs.ofs: 158 */ + u8 reserved7[13]; +#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */ + u8 board_pba_number_4965[9]; /* abs.ofs: 173 */ + u8 reserved8[10]; +#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */ + u8 sku_id[4]; /* abs.ofs: 192 */ + +/* + * Per-channel regulatory data. + * + * Each channel that *might* be supported by 3945 or 4965 has a fixed location + * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory + * txpower (MSB). + * + * Entries immediately below are for 20 MHz channel width. FAT (40 MHz) + * channels (only for 4965, not supported by 3945) appear later in the EEPROM. + * + * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + */ +#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */ + u16 band_1_count; /* abs.ofs: 196 */ +#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */ + struct iwl4965_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */ + +/* + * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196, + * 5.0 GHz channels 7, 8, 11, 12, 16 + * (4915-5080MHz) (none of these is ever supported) + */ +#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */ + u16 band_2_count; /* abs.ofs: 226 */ +#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */ + struct iwl4965_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ + +/* + * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 + * (5170-5320MHz) + */ +#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */ + u16 band_3_count; /* abs.ofs: 254 */ +#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */ + struct iwl4965_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ + +/* + * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 + * (5500-5700MHz) + */ +#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */ + u16 band_4_count; /* abs.ofs: 280 */ +#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */ + struct iwl4965_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ + +/* + * 5.7 GHz channels 145, 149, 153, 157, 161, 165 + * (5725-5825MHz) + */ +#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */ + u16 band_5_count; /* abs.ofs: 304 */ +#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */ + struct iwl4965_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ + + u8 reserved10[2]; + + +/* + * 2.4 GHz FAT channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11) + * + * The channel listed is the center of the lower 20 MHz half of the channel. + * The overall center frequency is actually 2 channels (10 MHz) above that, + * and the upper half of each FAT channel is centered 4 channels (20 MHz) away + * from the lower half; e.g. the upper half of FAT channel 1 is channel 5, + * and the overall FAT channel width centers on channel 3. + * + * NOTE: The RXON command uses 20 MHz channel numbers to specify the + * control channel to which to tune. RXON also specifies whether the + * control channel is the upper or lower half of a FAT channel. + * + * NOTE: 4965 does not support FAT channels on 2.4 GHz. + */ +#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0) /* 14 bytes */ + struct iwl4965_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */ + u8 reserved11[2]; + +/* + * 5.2 GHz FAT channels 36 (40), 44 (48), 52 (56), 60 (64), + * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161) + */ +#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */ + struct iwl4965_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */ + u8 reserved12[6]; + +/* + * 4965 driver requires txpower calibration format version 5 or greater. + * Driver does not work with txpower calibration version < 5. + * This value is simply a 16-bit number, no major/minor versions here. + */ +#define EEPROM_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */ + u16 calib_version; /* abs.ofs: 364 */ + u8 reserved13[2]; + u8 reserved14[96]; /* abs.ofs: 368 */ + +/* + * 4965 Txpower calibration data. + */ +#define EEPROM_IWL_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */ + struct iwl4965_eeprom_calib_info calib_info; /* abs.ofs: 464 */ + + u8 reserved16[140]; /* fill out to full 1024 byte block */ + + +} __attribute__ ((packed)); + +#define IWL_EEPROM_IMAGE_SIZE 1024 + +/* End of EEPROM */ + +#include "iwl-4965-commands.h" + +#define PCI_LINK_CTRL 0x0F0 +#define PCI_POWER_SOURCE 0x0C8 +#define PCI_REG_WUM8 0x0E8 +#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) + +/*=== CSR (control and status registers) ===*/ +#define CSR_BASE (0x000) + +#define CSR_SW_VER (CSR_BASE+0x000) +#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ +#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ +#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ +#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ +#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ +#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */ +#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ +#define CSR_GP_CNTRL (CSR_BASE+0x024) + +/* + * Hardware revision info + * Bit fields: + * 31-8: Reserved + * 7-4: Type of device: 0x0 = 4965, 0xd = 3945 + * 3-2: Revision step: 0 = A, 1 = B, 2 = C, 3 = D + * 1-0: "Dash" value, as in A-1, etc. + * + * NOTE: Revision step affects calculation of CCK txpower for 4965. + */ +#define CSR_HW_REV (CSR_BASE+0x028) + +/* EEPROM reads */ +#define CSR_EEPROM_REG (CSR_BASE+0x02c) +#define CSR_EEPROM_GP (CSR_BASE+0x030) +#define CSR_GP_UCODE (CSR_BASE+0x044) +#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) +#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) +#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) +#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) +#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) + +/* + * Indicates hardware rev, to determine CCK backoff for txpower calculation. + * Bit fields: + * 3-2: 0 = A, 1 = B, 2 = C, 3 = D step + */ +#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) + +/* Hardware interface configuration bits */ +#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R (0x00000010) +#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) +#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) +#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) + +/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), + * acknowledged (reset) by host writing "1" to flagged bits. */ +#define CSR_INT_BIT_FH_RX (1<<31) /* Rx DMA, cmd responses, FH_INT[17:16] */ +#define CSR_INT_BIT_HW_ERR (1<<29) /* DMA hardware error FH_INT[31] */ +#define CSR_INT_BIT_DNLD (1<<28) /* uCode Download */ +#define CSR_INT_BIT_FH_TX (1<<27) /* Tx DMA FH_INT[1:0] */ +#define CSR_INT_BIT_MAC_CLK_ACTV (1<<26) /* NIC controller's clock toggled on/off */ +#define CSR_INT_BIT_SW_ERR (1<<25) /* uCode error */ +#define CSR_INT_BIT_RF_KILL (1<<7) /* HW RFKILL switch GP_CNTRL[27] toggled */ +#define CSR_INT_BIT_CT_KILL (1<<6) /* Critical temp (chip too hot) rfkill */ +#define CSR_INT_BIT_SW_RX (1<<3) /* Rx, command responses, 3945 */ +#define CSR_INT_BIT_WAKEUP (1<<1) /* NIC controller waking up (pwr mgmt) */ +#define CSR_INT_BIT_ALIVE (1<<0) /* uCode interrupts once it initializes */ + +#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ + CSR_INT_BIT_HW_ERR | \ + CSR_INT_BIT_FH_TX | \ + CSR_INT_BIT_SW_ERR | \ + CSR_INT_BIT_RF_KILL | \ + CSR_INT_BIT_SW_RX | \ + CSR_INT_BIT_WAKEUP | \ + CSR_INT_BIT_ALIVE) + +/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ +#define CSR_FH_INT_BIT_ERR (1<<31) /* Error */ +#define CSR_FH_INT_BIT_HI_PRIOR (1<<30) /* High priority Rx, bypass coalescing */ +#define CSR_FH_INT_BIT_RX_CHNL1 (1<<17) /* Rx channel 1 */ +#define CSR_FH_INT_BIT_RX_CHNL0 (1<<16) /* Rx channel 0 */ +#define CSR_FH_INT_BIT_TX_CHNL1 (1<<1) /* Tx channel 1 */ +#define CSR_FH_INT_BIT_TX_CHNL0 (1<<0) /* Tx channel 0 */ + +#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ + CSR_FH_INT_BIT_RX_CHNL1 | \ + CSR_FH_INT_BIT_RX_CHNL0) + +#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL1 | \ + CSR_FH_INT_BIT_TX_CHNL0) + + +/* RESET */ +#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001) +#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002) +#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) +#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) +#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) + +/* GP (general purpose) CONTROL */ +#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) +#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) +#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) +#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) + +#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001) + +#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000) +#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000) +#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) + + +/* EEPROM REG */ +#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) +#define CSR_EEPROM_REG_BIT_CMD (0x00000002) + +/* EEPROM GP */ +#define CSR_EEPROM_GP_VALID_MSK (0x00000006) +#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000) +#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) + +/* UCODE DRV GP */ +#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) +#define CSR_UCODE_SW_BIT_RFKILL (0x00000002) +#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) +#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) + +/* GPIO */ +#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) +#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000) +#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER + +/* GI Chicken Bits */ +#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) +#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) + +/*=== HBUS (Host-side Bus) ===*/ +#define HBUS_BASE (0x400) + +/* + * Registers for accessing device's internal SRAM memory (e.g. SCD SRAM + * structures, error log, event log, verifying uCode load). + * First write to address register, then read from or write to data register + * to complete the job. Once the address register is set up, accesses to + * data registers auto-increment the address by one dword. + * Bit usage for address registers (read or write): + * 0-31: memory address within device + */ +#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c) +#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010) +#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) +#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) + +/* + * Registers for accessing device's internal peripheral registers + * (e.g. SCD, BSM, etc.). First write to address register, + * then read from or write to data register to complete the job. + * Bit usage for address registers (read or write): + * 0-15: register address (offset) within device + * 24-25: (# bytes - 1) to read or write (e.g. 3 for dword) + */ +#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044) +#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048) +#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) +#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) + +/* + * Per-Tx-queue write pointer (index, really!) (3945 and 4965). + * Driver sets this to indicate index to next TFD that driver will fill + * (1 past latest filled). + * Bit usage: + * 0-7: queue write index (0-255) + * 11-8: queue selector (0-15) + */ +#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) + +#define HBUS_TARG_MBX_C (HBUS_BASE+0x030) + +#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) + +#define TFD_QUEUE_SIZE_MAX (256) + +#define IWL_NUM_SCAN_RATES (2) + +#define IWL_DEFAULT_TX_RETRY 15 + +#define RX_QUEUE_SIZE 256 +#define RX_QUEUE_MASK 255 +#define RX_QUEUE_SIZE_LOG 8 + +#define TFD_TX_CMD_SLOTS 256 +#define TFD_CMD_SLOTS 32 + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \ + sizeof(struct iwl4965_cmd_meta)) + +/* + * RX related structures and functions + */ +#define RX_FREE_BUFFERS 64 +#define RX_LOW_WATERMARK 8 + +/* Size of one Rx buffer in host DRAM */ +#define IWL_RX_BUF_SIZE_4K (4 * 1024) +#define IWL_RX_BUF_SIZE_8K (8 * 1024) + +/* Sizes and addresses for instruction and data memory (SRAM) in + * 4965's embedded processor. Driver access is via HBUS_TARG_MEM_* regs. */ +#define RTC_INST_LOWER_BOUND (0x000000) #define KDR_RTC_INST_UPPER_BOUND (0x018000) + +#define RTC_DATA_LOWER_BOUND (0x800000) #define KDR_RTC_DATA_UPPER_BOUND (0x80A000) + #define KDR_RTC_INST_SIZE (KDR_RTC_INST_UPPER_BOUND - RTC_INST_LOWER_BOUND) #define KDR_RTC_DATA_SIZE (KDR_RTC_DATA_UPPER_BOUND - RTC_DATA_LOWER_BOUND) #define IWL_MAX_INST_SIZE KDR_RTC_INST_SIZE #define IWL_MAX_DATA_SIZE KDR_RTC_DATA_SIZE -static inline int iwl_hw_valid_rtc_data_addr(u32 addr) +/* Size of uCode instruction memory in bootstrap state machine */ +#define IWL_MAX_BSM_SIZE BSM_SRAM_SIZE + +static inline int iwl4965_hw_valid_rtc_data_addr(u32 addr) { return (addr >= RTC_DATA_LOWER_BOUND) && (addr < KDR_RTC_DATA_UPPER_BOUND); } -/********************* START TXPOWER *****************************************/ -enum { - HT_IE_EXT_CHANNEL_NONE = 0, - HT_IE_EXT_CHANNEL_ABOVE, - HT_IE_EXT_CHANNEL_INVALID, - HT_IE_EXT_CHANNEL_BELOW, - HT_IE_EXT_CHANNEL_MAX -}; - -enum { - CALIB_CH_GROUP_1 = 0, - CALIB_CH_GROUP_2 = 1, - CALIB_CH_GROUP_3 = 2, - CALIB_CH_GROUP_4 = 3, - CALIB_CH_GROUP_5 = 4, - CALIB_CH_GROUP_MAX -}; +/********************* START TEMPERATURE *************************************/ -/* Temperature calibration offset is 3% 0C in Kelvin */ +/** + * 4965 temperature calculation. + * + * The driver must calculate the device temperature before calculating + * a txpower setting (amplifier gain is temperature dependent). The + * calculation uses 4 measurements, 3 of which (R1, R2, R3) are calibration + * values used for the life of the driver, and one of which (R4) is the + * real-time temperature indicator. + * + * uCode provides all 4 values to the driver via the "initialize alive" + * notification (see struct iwl4965_init_alive_resp). After the runtime uCode + * image loads, uCode updates the R4 value via statistics notifications + * (see STATISTICS_NOTIFICATION), which occur after each received beacon + * when associated, or can be requested via REPLY_STATISTICS_CMD. + * + * NOTE: uCode provides the R4 value as a 23-bit signed value. Driver + * must sign-extend to 32 bits before applying formula below. + * + * Formula: + * + * degrees Kelvin = ((97 * 259 * (R4 - R2) / (R3 - R1)) / 100) + 8 + * + * NOTE: The basic formula is 259 * (R4-R2) / (R3-R1). The 97/100 is + * an additional correction, which should be centered around 0 degrees + * Celsius (273 degrees Kelvin). The 8 (3 percent of 273) compensates for + * centering the 97/100 correction around 0 degrees K. + * + * Add 273 to Kelvin value to find degrees Celsius, for comparing current + * temperature with factory-measured temperatures when calculating txpower + * settings. + */ #define TEMPERATURE_CALIB_KELVIN_OFFSET 8 #define TEMPERATURE_CALIB_A_VAL 259 +/* Limit range of calculated temperature to be between these Kelvin values */ #define IWL_TX_POWER_TEMPERATURE_MIN (263) #define IWL_TX_POWER_TEMPERATURE_MAX (410) @@ -109,228 +679,875 @@ enum { (((t) < IWL_TX_POWER_TEMPERATURE_MIN) || \ ((t) > IWL_TX_POWER_TEMPERATURE_MAX)) -#define IWL_TX_POWER_ILLEGAL_TEMPERATURE (300) +/********************* END TEMPERATURE ***************************************/ -#define IWL_TX_POWER_TEMPERATURE_DIFFERENCE (2) +/********************* START TXPOWER *****************************************/ -#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) +/** + * 4965 txpower calculations rely on information from three sources: + * + * 1) EEPROM + * 2) "initialize" alive notification + * 3) statistics notifications + * + * EEPROM data consists of: + * + * 1) Regulatory information (max txpower and channel usage flags) is provided + * separately for each channel that can possibly supported by 4965. + * 40 MHz wide (.11n fat) channels are listed separately from 20 MHz + * (legacy) channels. + * + * See struct iwl4965_eeprom_channel for format, and struct iwl4965_eeprom + * for locations in EEPROM. + * + * 2) Factory txpower calibration information is provided separately for + * sub-bands of contiguous channels. 2.4GHz has just one sub-band, + * but 5 GHz has several sub-bands. + * + * In addition, per-band (2.4 and 5 Ghz) saturation txpowers are provided. + * + * See struct iwl4965_eeprom_calib_info (and the tree of structures + * contained within it) for format, and struct iwl4965_eeprom for + * locations in EEPROM. + * + * "Initialization alive" notification (see struct iwl4965_init_alive_resp) + * consists of: + * + * 1) Temperature calculation parameters. + * + * 2) Power supply voltage measurement. + * + * 3) Tx gain compensation to balance 2 transmitters for MIMO use. + * + * Statistics notifications deliver: + * + * 1) Current values for temperature param R4. + */ + +/** + * To calculate a txpower setting for a given desired target txpower, channel, + * modulation bit rate, and transmitter chain (4965 has 2 transmitters to + * support MIMO and transmit diversity), driver must do the following: + * + * 1) Compare desired txpower vs. (EEPROM) regulatory limit for this channel. + * Do not exceed regulatory limit; reduce target txpower if necessary. + * + * If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * 2 transmitters will be used simultaneously; driver must reduce the + * regulatory limit by 3 dB (half-power) for each transmitter, so the + * combined total output of the 2 transmitters is within regulatory limits. + * + * + * 2) Compare target txpower vs. (EEPROM) saturation txpower *reduced by + * backoff for this bit rate*. Do not exceed (saturation - backoff[rate]); + * reduce target txpower if necessary. + * + * Backoff values below are in 1/2 dB units (equivalent to steps in + * txpower gain tables): + * + * OFDM 6 - 36 MBit: 10 steps (5 dB) + * OFDM 48 MBit: 15 steps (7.5 dB) + * OFDM 54 MBit: 17 steps (8.5 dB) + * OFDM 60 MBit: 20 steps (10 dB) + * CCK all rates: 10 steps (5 dB) + * + * Backoff values apply to saturation txpower on a per-transmitter basis; + * when using MIMO (2 transmitters), each transmitter uses the same + * saturation level provided in EEPROM, and the same backoff values; + * no reduction (such as with regulatory txpower limits) is required. + * + * Saturation and Backoff values apply equally to 20 Mhz (legacy) channel + * widths and 40 Mhz (.11n fat) channel widths; there is no separate + * factory measurement for fat channels. + * + * The result of this step is the final target txpower. The rest of + * the steps figure out the proper settings for the device to achieve + * that target txpower. + * + * + * 3) Determine (EEPROM) calibration subband for the target channel, by + * comparing against first and last channels in each subband + * (see struct iwl4965_eeprom_calib_subband_info). + * + * + * 4) Linearly interpolate (EEPROM) factory calibration measurement sets, + * referencing the 2 factory-measured (sample) channels within the subband. + * + * Interpolation is based on difference between target channel's frequency + * and the sample channels' frequencies. Since channel numbers are based + * on frequency (5 MHz between each channel number), this is equivalent + * to interpolating based on channel number differences. + * + * Note that the sample channels may or may not be the channels at the + * edges of the subband. The target channel may be "outside" of the + * span of the sampled channels. + * + * Driver may choose the pair (for 2 Tx chains) of measurements (see + * struct iwl4965_eeprom_calib_ch_info) for which the actual measured + * txpower comes closest to the desired txpower. Usually, though, + * the middle set of measurements is closest to the regulatory limits, + * and is therefore a good choice for all txpower calculations (this + * assumes that high accuracy is needed for maximizing legal txpower, + * while lower txpower configurations do not need as much accuracy). + * + * Driver should interpolate both members of the chosen measurement pair, + * i.e. for both Tx chains (radio transmitters), unless the driver knows + * that only one of the chains will be used (e.g. only one tx antenna + * connected, but this should be unusual). The rate scaling algorithm + * switches antennas to find best performance, so both Tx chains will + * be used (although only one at a time) even for non-MIMO transmissions. + * + * Driver should interpolate factory values for temperature, gain table + * index, and actual power. The power amplifier detector values are + * not used by the driver. + * + * Sanity check: If the target channel happens to be one of the sample + * channels, the results should agree with the sample channel's + * measurements! + * + * + * 5) Find difference between desired txpower and (interpolated) + * factory-measured txpower. Using (interpolated) factory gain table index + * (shown elsewhere) as a starting point, adjust this index lower to + * increase txpower, or higher to decrease txpower, until the target + * txpower is reached. Each step in the gain table is 1/2 dB. + * + * For example, if factory measured txpower is 16 dBm, and target txpower + * is 13 dBm, add 6 steps to the factory gain index to reduce txpower + * by 3 dB. + * + * + * 6) Find difference between current device temperature and (interpolated) + * factory-measured temperature for sub-band. Factory values are in + * degrees Celsius. To calculate current temperature, see comments for + * "4965 temperature calculation". + * + * If current temperature is higher than factory temperature, driver must + * increase gain (lower gain table index), and vice versa. + * + * Temperature affects gain differently for different channels: + * + * 2.4 GHz all channels: 3.5 degrees per half-dB step + * 5 GHz channels 34-43: 4.5 degrees per half-dB step + * 5 GHz channels >= 44: 4.0 degrees per half-dB step + * + * NOTE: Temperature can increase rapidly when transmitting, especially + * with heavy traffic at high txpowers. Driver should update + * temperature calculations often under these conditions to + * maintain strong txpower in the face of rising temperature. + * + * + * 7) Find difference between current power supply voltage indicator + * (from "initialize alive") and factory-measured power supply voltage + * indicator (EEPROM). + * + * If the current voltage is higher (indicator is lower) than factory + * voltage, gain should be reduced (gain table index increased) by: + * + * (eeprom - current) / 7 + * + * If the current voltage is lower (indicator is higher) than factory + * voltage, gain should be increased (gain table index decreased) by: + * + * 2 * (current - eeprom) / 7 + * + * If number of index steps in either direction turns out to be > 2, + * something is wrong ... just use 0. + * + * NOTE: Voltage compensation is independent of band/channel. + * + * NOTE: "Initialize" uCode measures current voltage, which is assumed + * to be constant after this initial measurement. Voltage + * compensation for txpower (number of steps in gain table) + * may be calculated once and used until the next uCode bootload. + * + * + * 8) If setting up txpowers for MIMO rates (rate indexes 8-15, 24-31), + * adjust txpower for each transmitter chain, so txpower is balanced + * between the two chains. There are 5 pairs of tx_atten[group][chain] + * values in "initialize alive", one pair for each of 5 channel ranges: + * + * Group 0: 5 GHz channel 34-43 + * Group 1: 5 GHz channel 44-70 + * Group 2: 5 GHz channel 71-124 + * Group 3: 5 GHz channel 125-200 + * Group 4: 2.4 GHz all channels + * + * Add the tx_atten[group][chain] value to the index for the target chain. + * The values are signed, but are in pairs of 0 and a non-negative number, + * so as to reduce gain (if necessary) of the "hotter" channel. This + * avoids any need to double-check for regulatory compliance after + * this step. + * + * + * 9) If setting up for a CCK rate, lower the gain by adding a CCK compensation + * value to the index: + * + * Hardware rev B: 9 steps (4.5 dB) + * Hardware rev C: 5 steps (2.5 dB) + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + * + * NOTE: This compensation is in addition to any saturation backoff that + * might have been applied in an earlier step. + * + * + * 10) Select the gain table, based on band (2.4 vs 5 GHz). + * + * Limit the adjusted index to stay within the table! + * + * + * 11) Read gain table entries for DSP and radio gain, place into appropriate + * location(s) in command (struct iwl4965_txpowertable_cmd). + */ +/* Limit range of txpower output target to be between these values */ #define IWL_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm = 1 milliwatt */ #define IWL_TX_POWER_TARGET_POWER_MAX (16) /* 16 dBm */ -/* timeout equivalent to 3 minutes */ -#define IWL_TX_POWER_TIMELIMIT_NOCALIB 1800000000 - -#define IWL_TX_POWER_CCK_COMPENSATION (9) - -#define MIN_TX_GAIN_INDEX (0) -#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) -#define MAX_TX_GAIN_INDEX_52GHZ (98) -#define MIN_TX_GAIN_52GHZ (98) -#define MAX_TX_GAIN_INDEX_24GHZ (98) -#define MIN_TX_GAIN_24GHZ (98) -#define MAX_TX_GAIN (0) -#define MAX_TX_GAIN_52GHZ_EXT (-9) +/** + * When MIMO is used (2 transmitters operating simultaneously), driver should + * limit each transmitter to deliver a max of 3 dB below the regulatory limit + * for the device. That is, use half power for each transmitter, so total + * txpower is within regulatory limits. + * + * The value "6" represents number of steps in gain table to reduce power 3 dB. + * Each step is 1/2 dB. + */ +#define IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION (6) +/** + * CCK gain compensation. + * + * When calculating txpowers for CCK, after making sure that the target power + * is within regulatory and saturation limits, driver must additionally + * back off gain by adding these values to the gain table index. + * + * Hardware rev for 4965 can be determined by reading CSR_HW_REV_WA_REG, + * bits [3:2], 1 = B, 2 = C. + */ +#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) +#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) + +/* + * 4965 power supply voltage compensation for txpower + */ +#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V (7) + +/** + * Gain tables. + * + * The following tables contain pair of values for setting txpower, i.e. + * gain settings for the output of the device's digital signal processor (DSP), + * and for the analog gain structure of the transmitter. + * + * Each entry in the gain tables represents a step of 1/2 dB. Note that these + * are *relative* steps, not indications of absolute output power. Output + * power varies with temperature, voltage, and channel frequency, and also + * requires consideration of average power (to satisfy regulatory constraints), + * and peak power (to avoid distortion of the output signal). + * + * Each entry contains two values: + * 1) DSP gain (or sometimes called DSP attenuation). This is a fine-grained + * linear value that multiplies the output of the digital signal processor, + * before being sent to the analog radio. + * 2) Radio gain. This sets the analog gain of the radio Tx path. + * It is a coarser setting, and behaves in a logarithmic (dB) fashion. + * + * EEPROM contains factory calibration data for txpower. This maps actual + * measured txpower levels to gain settings in the "well known" tables + * below ("well-known" means here that both factory calibration *and* the + * driver work with the same table). + * + * There are separate tables for 2.4 GHz and 5 GHz bands. The 5 GHz table + * has an extension (into negative indexes), in case the driver needs to + * boost power setting for high device temperatures (higher than would be + * present during factory calibration). A 5 Ghz EEPROM index of "40" + * corresponds to the 49th entry in the table used by the driver. + */ +#define MIN_TX_GAIN_INDEX (0) /* highest gain, lowest idx, 2.4 */ +#define MIN_TX_GAIN_INDEX_52GHZ_EXT (-9) /* highest gain, lowest idx, 5 */ + +/** + * 2.4 GHz gain table + * + * Index Dsp gain Radio gain + * 0 110 0x3f (highest gain) + * 1 104 0x3f + * 2 98 0x3f + * 3 110 0x3e + * 4 104 0x3e + * 5 98 0x3e + * 6 110 0x3d + * 7 104 0x3d + * 8 98 0x3d + * 9 110 0x3c + * 10 104 0x3c + * 11 98 0x3c + * 12 110 0x3b + * 13 104 0x3b + * 14 98 0x3b + * 15 110 0x3a + * 16 104 0x3a + * 17 98 0x3a + * 18 110 0x39 + * 19 104 0x39 + * 20 98 0x39 + * 21 110 0x38 + * 22 104 0x38 + * 23 98 0x38 + * 24 110 0x37 + * 25 104 0x37 + * 26 98 0x37 + * 27 110 0x36 + * 28 104 0x36 + * 29 98 0x36 + * 30 110 0x35 + * 31 104 0x35 + * 32 98 0x35 + * 33 110 0x34 + * 34 104 0x34 + * 35 98 0x34 + * 36 110 0x33 + * 37 104 0x33 + * 38 98 0x33 + * 39 110 0x32 + * 40 104 0x32 + * 41 98 0x32 + * 42 110 0x31 + * 43 104 0x31 + * 44 98 0x31 + * 45 110 0x30 + * 46 104 0x30 + * 47 98 0x30 + * 48 110 0x6 + * 49 104 0x6 + * 50 98 0x6 + * 51 110 0x5 + * 52 104 0x5 + * 53 98 0x5 + * 54 110 0x4 + * 55 104 0x4 + * 56 98 0x4 + * 57 110 0x3 + * 58 104 0x3 + * 59 98 0x3 + * 60 110 0x2 + * 61 104 0x2 + * 62 98 0x2 + * 63 110 0x1 + * 64 104 0x1 + * 65 98 0x1 + * 66 110 0x0 + * 67 104 0x0 + * 68 98 0x0 + * 69 97 0 + * 70 96 0 + * 71 95 0 + * 72 94 0 + * 73 93 0 + * 74 92 0 + * 75 91 0 + * 76 90 0 + * 77 89 0 + * 78 88 0 + * 79 87 0 + * 80 86 0 + * 81 85 0 + * 82 84 0 + * 83 83 0 + * 84 82 0 + * 85 81 0 + * 86 80 0 + * 87 79 0 + * 88 78 0 + * 89 77 0 + * 90 76 0 + * 91 75 0 + * 92 74 0 + * 93 73 0 + * 94 72 0 + * 95 71 0 + * 96 70 0 + * 97 69 0 + * 98 68 0 + */ + +/** + * 5 GHz gain table + * + * Index Dsp gain Radio gain + * -9 123 0x3F (highest gain) + * -8 117 0x3F + * -7 110 0x3F + * -6 104 0x3F + * -5 98 0x3F + * -4 110 0x3E + * -3 104 0x3E + * -2 98 0x3E + * -1 110 0x3D + * 0 104 0x3D + * 1 98 0x3D + * 2 110 0x3C + * 3 104 0x3C + * 4 98 0x3C + * 5 110 0x3B + * 6 104 0x3B + * 7 98 0x3B + * 8 110 0x3A + * 9 104 0x3A + * 10 98 0x3A + * 11 110 0x39 + * 12 104 0x39 + * 13 98 0x39 + * 14 110 0x38 + * 15 104 0x38 + * 16 98 0x38 + * 17 110 0x37 + * 18 104 0x37 + * 19 98 0x37 + * 20 110 0x36 + * 21 104 0x36 + * 22 98 0x36 + * 23 110 0x35 + * 24 104 0x35 + * 25 98 0x35 + * 26 110 0x34 + * 27 104 0x34 + * 28 98 0x34 + * 29 110 0x33 + * 30 104 0x33 + * 31 98 0x33 + * 32 110 0x32 + * 33 104 0x32 + * 34 98 0x32 + * 35 110 0x31 + * 36 104 0x31 + * 37 98 0x31 + * 38 110 0x30 + * 39 104 0x30 + * 40 98 0x30 + * 41 110 0x25 + * 42 104 0x25 + * 43 98 0x25 + * 44 110 0x24 + * 45 104 0x24 + * 46 98 0x24 + * 47 110 0x23 + * 48 104 0x23 + * 49 98 0x23 + * 50 110 0x22 + * 51 104 0x18 + * 52 98 0x18 + * 53 110 0x17 + * 54 104 0x17 + * 55 98 0x17 + * 56 110 0x16 + * 57 104 0x16 + * 58 98 0x16 + * 59 110 0x15 + * 60 104 0x15 + * 61 98 0x15 + * 62 110 0x14 + * 63 104 0x14 + * 64 98 0x14 + * 65 110 0x13 + * 66 104 0x13 + * 67 98 0x13 + * 68 110 0x12 + * 69 104 0x08 + * 70 98 0x08 + * 71 110 0x07 + * 72 104 0x07 + * 73 98 0x07 + * 74 110 0x06 + * 75 104 0x06 + * 76 98 0x06 + * 77 110 0x05 + * 78 104 0x05 + * 79 98 0x05 + * 80 110 0x04 + * 81 104 0x04 + * 82 98 0x04 + * 83 110 0x03 + * 84 104 0x03 + * 85 98 0x03 + * 86 110 0x02 + * 87 104 0x02 + * 88 98 0x02 + * 89 110 0x01 + * 90 104 0x01 + * 91 98 0x01 + * 92 110 0x00 + * 93 104 0x00 + * 94 98 0x00 + * 95 93 0x00 + * 96 88 0x00 + * 97 83 0x00 + * 98 78 0x00 + */ + + +/** + * Sanity checks and default values for EEPROM regulatory levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Regulatory limits refer to the maximum average txpower allowed by + * regulatory agencies in the geographies in which the device is meant + * to be operated. These limits are SKU-specific (i.e. geography-specific), + * and channel-specific; each channel has an individual regulatory limit + * listed in the EEPROM. + * + * Units are in half-dBm (i.e. "34" means 17 dBm). + */ #define IWL_TX_POWER_DEFAULT_REGULATORY_24 (34) #define IWL_TX_POWER_DEFAULT_REGULATORY_52 (34) #define IWL_TX_POWER_REGULATORY_MIN (0) #define IWL_TX_POWER_REGULATORY_MAX (34) + +/** + * Sanity checks and default values for EEPROM saturation levels. + * If EEPROM values fall outside MIN/MAX range, use default values. + * + * Saturation is the highest level that the output power amplifier can produce + * without significant clipping distortion. This is a "peak" power level. + * Different types of modulation (i.e. various "rates", and OFDM vs. CCK) + * require differing amounts of backoff, relative to their average power output, + * in order to avoid clipping distortion. + * + * Driver must make sure that it is violating neither the saturation limit, + * nor the regulatory limit, when calculating Tx power settings for various + * rates. + * + * Units are in half-dBm (i.e. "38" means 19 dBm). + */ #define IWL_TX_POWER_DEFAULT_SATURATION_24 (38) #define IWL_TX_POWER_DEFAULT_SATURATION_52 (38) #define IWL_TX_POWER_SATURATION_MIN (20) #define IWL_TX_POWER_SATURATION_MAX (50) -/* dv *0.4 = dt; so that 5 degrees temperature diff equals - * 12.5 in voltage diff */ -#define IWL_TX_TEMPERATURE_UPDATE_LIMIT 9 - -#define IWL_INVALID_CHANNEL (0xffffffff) -#define IWL_TX_POWER_REGITRY_BIT (2) - -#define MIN_IWL_TX_POWER_CALIB_DUR (100) -#define IWL_CCK_FROM_OFDM_POWER_DIFF (-5) -#define IWL_CCK_FROM_OFDM_INDEX_DIFF (9) - -/* Number of entries in the gain table */ -#define POWER_GAIN_NUM_ENTRIES 78 -#define TX_POW_MAX_SESSION_NUM 5 -/* timeout equivalent to 3 minutes */ -#define TX_IWL_TIMELIMIT_NOCALIB 1800000000 - -/* Kedron TX_CALIB_STATES */ -#define IWL_TX_CALIB_STATE_SEND_TX 0x00000001 -#define IWL_TX_CALIB_WAIT_TX_RESPONSE 0x00000002 -#define IWL_TX_CALIB_ENABLED 0x00000004 -#define IWL_TX_CALIB_XVT_ON 0x00000008 -#define IWL_TX_CALIB_TEMPERATURE_CORRECT 0x00000010 -#define IWL_TX_CALIB_WORKING_WITH_XVT 0x00000020 -#define IWL_TX_CALIB_XVT_PERIODICAL 0x00000040 - -#define NUM_IWL_TX_CALIB_SETTINS 5 /* Number of tx correction groups */ - -#define IWL_MIN_POWER_IN_VP_TABLE 1 /* 0.5dBm multiplied by 2 */ -#define IWL_MAX_POWER_IN_VP_TABLE 40 /* 20dBm - multiplied by 2 (because - * entries are for each 0.5dBm) */ -#define IWL_STEP_IN_VP_TABLE 1 /* 0.5dB - multiplied by 2 */ -#define IWL_NUM_POINTS_IN_VPTABLE \ - (1 + IWL_MAX_POWER_IN_VP_TABLE - IWL_MIN_POWER_IN_VP_TABLE) - -#define MIN_TX_GAIN_INDEX (0) -#define MAX_TX_GAIN_INDEX_52GHZ (98) -#define MIN_TX_GAIN_52GHZ (98) -#define MAX_TX_GAIN_INDEX_24GHZ (98) -#define MIN_TX_GAIN_24GHZ (98) -#define MAX_TX_GAIN (0) - -/* First and last channels of all groups */ +/** + * Channel groups used for Tx Attenuation calibration (MIMO tx channel balance) + * and thermal Txpower calibration. + * + * When calculating txpower, driver must compensate for current device + * temperature; higher temperature requires higher gain. Driver must calculate + * current temperature (see "4965 temperature calculation"), then compare vs. + * factory calibration temperature in EEPROM; if current temperature is higher + * than factory temperature, driver must *increase* gain by proportions shown + * in table below. If current temperature is lower than factory, driver must + * *decrease* gain. + * + * Different frequency ranges require different compensation, as shown below. + */ +/* Group 0, 5.2 GHz ch 34-43: 4.5 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR1_FCH 34 #define CALIB_IWL_TX_ATTEN_GR1_LCH 43 + +/* Group 1, 5.3 GHz ch 44-70: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR2_FCH 44 #define CALIB_IWL_TX_ATTEN_GR2_LCH 70 + +/* Group 2, 5.5 GHz ch 71-124: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR3_FCH 71 #define CALIB_IWL_TX_ATTEN_GR3_LCH 124 + +/* Group 3, 5.7 GHz ch 125-200: 4.0 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR4_FCH 125 #define CALIB_IWL_TX_ATTEN_GR4_LCH 200 + +/* Group 4, 2.4 GHz all channels: 3.5 degrees per 1/2 dB. */ #define CALIB_IWL_TX_ATTEN_GR5_FCH 1 #define CALIB_IWL_TX_ATTEN_GR5_LCH 20 - -union iwl_tx_power_dual_stream { - struct { - u8 radio_tx_gain[2]; - u8 dsp_predis_atten[2]; - } s; - u32 dw; +enum { + CALIB_CH_GROUP_1 = 0, + CALIB_CH_GROUP_2 = 1, + CALIB_CH_GROUP_3 = 2, + CALIB_CH_GROUP_4 = 3, + CALIB_CH_GROUP_5 = 4, + CALIB_CH_GROUP_MAX }; /********************* END TXPOWER *****************************************/ -/* HT flags */ -#define RXON_FLG_CTRL_CHANNEL_LOC_POS (22) -#define RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK __constant_cpu_to_le32(0x1<<22) - -#define RXON_FLG_HT_OPERATING_MODE_POS (23) - -#define RXON_FLG_HT_PROT_MSK __constant_cpu_to_le32(0x1<<23) -#define RXON_FLG_FAT_PROT_MSK __constant_cpu_to_le32(0x2<<23) - -#define RXON_FLG_CHANNEL_MODE_POS (25) -#define RXON_FLG_CHANNEL_MODE_MSK __constant_cpu_to_le32(0x3<<25) -#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK __constant_cpu_to_le32(0x1<<25) -#define RXON_FLG_CHANNEL_MODE_MIXED_MSK __constant_cpu_to_le32(0x2<<25) - -#define RXON_RX_CHAIN_DRIVER_FORCE_MSK __constant_cpu_to_le16(0x1<<0) -#define RXON_RX_CHAIN_VALID_MSK __constant_cpu_to_le16(0x7<<1) -#define RXON_RX_CHAIN_VALID_POS (1) -#define RXON_RX_CHAIN_FORCE_SEL_MSK __constant_cpu_to_le16(0x7<<4) -#define RXON_RX_CHAIN_FORCE_SEL_POS (4) -#define RXON_RX_CHAIN_FORCE_MIMO_SEL_MSK __constant_cpu_to_le16(0x7<<7) -#define RXON_RX_CHAIN_FORCE_MIMO_SEL_POS (7) -#define RXON_RX_CHAIN_CNT_MSK __constant_cpu_to_le16(0x3<<10) -#define RXON_RX_CHAIN_CNT_POS (10) -#define RXON_RX_CHAIN_MIMO_CNT_MSK __constant_cpu_to_le16(0x3<<12) -#define RXON_RX_CHAIN_MIMO_CNT_POS (12) -#define RXON_RX_CHAIN_MIMO_FORCE_MSK __constant_cpu_to_le16(0x1<<14) -#define RXON_RX_CHAIN_MIMO_FORCE_POS (14) - - -#define MCS_DUP_6M_PLCP 0x20 - -/* OFDM HT rate masks */ -/* ***************************************** */ -#define R_MCS_6M_MSK 0x1 -#define R_MCS_12M_MSK 0x2 -#define R_MCS_18M_MSK 0x4 -#define R_MCS_24M_MSK 0x8 -#define R_MCS_36M_MSK 0x10 -#define R_MCS_48M_MSK 0x20 -#define R_MCS_54M_MSK 0x40 -#define R_MCS_60M_MSK 0x80 -#define R_MCS_12M_DUAL_MSK 0x100 -#define R_MCS_24M_DUAL_MSK 0x200 -#define R_MCS_36M_DUAL_MSK 0x400 -#define R_MCS_48M_DUAL_MSK 0x800 - -#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) -#define is_siso(tbl) (((tbl) == LQ_SISO)) -#define is_mimo(tbl) (((tbl) == LQ_MIMO)) -#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) -#define is_a_band(tbl) (((tbl) == LQ_A)) -#define is_g_and(tbl) (((tbl) == LQ_G)) - +/****************************/ /* Flow Handler Definitions */ +/****************************/ -/**********************/ -/* Addresses */ -/**********************/ - +/** + * This I/O area is directly read/writable by driver (e.g. Linux uses writel()) + * Addresses are offsets from device's PCI hardware base address. + */ #define FH_MEM_LOWER_BOUND (0x1000) #define FH_MEM_UPPER_BOUND (0x1EF0) -#define IWL_FH_REGS_LOWER_BOUND (0x1000) -#define IWL_FH_REGS_UPPER_BOUND (0x2000) - +/** + * Keep-Warm (KW) buffer base address. + * + * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the + * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency + * DRAM access when 4965 is Txing or Rxing. The dummy accesses prevent host + * from going into a power-savings mode that would cause higher DRAM latency, + * and possible data over/under-runs, before all Tx/Rx is complete. + * + * Driver loads IWL_FH_KW_MEM_ADDR_REG with the physical address (bits 35:4) + * of the buffer, which must be 4K aligned. Once this is set up, the 4965 + * automatically invokes keep-warm accesses when normal accesses might not + * be sufficient to maintain fast DRAM response. + * + * Bit fields: + * 31-0: Keep-warm buffer physical base address [35:4], must be 4K aligned + */ #define IWL_FH_KW_MEM_ADDR_REG (FH_MEM_LOWER_BOUND + 0x97C) -/* CBBC Area - Circular buffers base address cache pointers table */ + +/** + * TFD Circular Buffers Base (CBBC) addresses + * + * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident + * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs) + * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 + * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte + * aligned (address bits 0-7 must be 0). + * + * Bit fields in each pointer register: + * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned + */ #define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) #define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) -/* queues 0 - 15 */ + +/* Find TFD CB base pointer for given queue (range 0-15). */ #define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) -/* RSCSR Area */ + +/** + * Rx SRAM Control and Status Registers (RSCSR) + * + * These registers provide handshake between driver and 4965 for the Rx queue + * (this queue handles *all* command responses, notifications, Rx data, etc. + * sent from 4965 uCode to host driver). Unlike Tx, there is only one Rx + * queue, and only one Rx DMA/FIFO channel. Also unlike Tx, which can + * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer + * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1 + * mapping between RBDs and RBs. + * + * Driver must allocate host DRAM memory for the following, and set the + * physical address of each into 4965 registers: + * + * 1) Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256 + * entries (although any power of 2, up to 4096, is selectable by driver). + * Each entry (1 dword) points to a receive buffer (RB) of consistent size + * (typically 4K, although 8K or 16K are also selectable by driver). + * Driver sets up RB size and number of RBDs in the CB via Rx config + * register FH_MEM_RCSR_CHNL0_CONFIG_REG. + * + * Bit fields within one RBD: + * 27-0: Receive Buffer physical address bits [35:8], 256-byte aligned + * + * Driver sets physical address [35:8] of base of RBD circular buffer + * into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0]. + * + * 2) Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers + * (RBs) have been filled, via a "write pointer", actually the index of + * the RB's corresponding RBD within the circular buffer. Driver sets + * physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0]. + * + * Bit fields in lower dword of Rx status buffer (upper dword not used + * by driver; see struct iwl4965_shared, val0): + * 31-12: Not used by driver + * 11- 0: Index of last filled Rx buffer descriptor + * (4965 writes, driver reads this value) + * + * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must + * enter pointers to these RBs into contiguous RBD circular buffer entries, + * and update the 4965's "write" index register, FH_RSCSR_CHNL0_RBDCB_WPTR_REG. + * + * This "write" index corresponds to the *next* RBD that the driver will make + * available, i.e. one RBD past the tail of the ready-to-fill RBDs within + * the circular buffer. This value should initially be 0 (before preparing any + * RBs), should be 8 after preparing the first 8 RBs (for example), and must + * wrap back to 0 at the end of the circular buffer (but don't wrap before + * "read" index has advanced past 1! See below). + * NOTE: 4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8. + * + * As the 4965 fills RBs (referenced from contiguous RBDs within the circular + * buffer), it updates the Rx status buffer in host DRAM, 2) described above, + * to tell the driver the index of the latest filled RBD. The driver must + * read this "read" index from DRAM after receiving an Rx interrupt from 4965. + * + * The driver must also internally keep track of a third index, which is the + * next RBD to process. When receiving an Rx interrupt, driver should process + * all filled but unprocessed RBs up to, but not including, the RB + * corresponding to the "read" index. For example, if "read" index becomes "1", + * driver may process the RB pointed to by RBD 0. Depending on volume of + * traffic, there may be many RBs to process. + * + * If read index == write index, 4965 thinks there is no room to put new data. + * Due to this, the maximum number of filled RBs is 255, instead of 256. To + * be safe, make sure that there is a gap of at least 2 RBDs between "write" + * and "read" indexes; that is, make sure that there are no more than 254 + * buffers waiting to be filled. + */ #define FH_MEM_RSCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBC0) #define FH_MEM_RSCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) #define FH_MEM_RSCSR_CHNL0 (FH_MEM_RSCSR_LOWER_BOUND) +/** + * Physical base address of 8-byte Rx Status buffer. + * Bit fields: + * 31-0: Rx status buffer physical base address [35:4], must 16-byte aligned. + */ #define FH_RSCSR_CHNL0_STTS_WPTR_REG (FH_MEM_RSCSR_CHNL0) + +/** + * Physical base address of Rx Buffer Descriptor Circular Buffer. + * Bit fields: + * 27-0: RBD CD physical base address [35:8], must be 256-byte aligned. + */ #define FH_RSCSR_CHNL0_RBDCB_BASE_REG (FH_MEM_RSCSR_CHNL0 + 0x004) + +/** + * Rx write pointer (index, really!). + * Bit fields: + * 11-0: Index of driver's most recent prepared-to-be-filled RBD, + 1. + * NOTE: For 256-entry circular buffer, use only bits [7:0]. + */ #define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008) +#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) + -/* RCSR Area - Registers address map */ +/** + * Rx Config/Status Registers (RCSR) + * Rx Config Reg for channel 0 (only channel used) + * + * Driver must initialize FH_MEM_RCSR_CHNL0_CONFIG_REG as follows for + * normal operation (see bit fields). + * + * Clearing FH_MEM_RCSR_CHNL0_CONFIG_REG to 0 turns off Rx DMA. + * Driver should poll FH_MEM_RSSR_RX_STATUS_REG for + * FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (bit 24) before continuing. + * + * Bit fields: + * 31-30: Rx DMA channel enable: '00' off/pause, '01' pause at end of frame, + * '10' operate normally + * 29-24: reserved + * 23-20: # RBDs in circular buffer = 2^value; use "8" for 256 RBDs (normal), + * min "5" for 32 RBDs, max "12" for 4096 RBDs. + * 19-18: reserved + * 17-16: size of each receive buffer; '00' 4K (normal), '01' 8K, + * '10' 12K, '11' 16K. + * 15-14: reserved + * 13-12: IRQ destination; '00' none, '01' host driver (normal operation) + * 11- 4: timeout for closing Rx buffer and interrupting host (units 32 usec) + * typical value 0x10 (about 1/2 msec) + * 3- 0: reserved + */ #define FH_MEM_RCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) #define FH_MEM_RCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xCC0) #define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND) #define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0) -/* RSSR Area - Rx shared ctrl & status registers */ +#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK (0x00000FF0) /* bit 4-11 */ +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK (0x00001000) /* bit 12 */ +#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000) /* bit 15 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK (0x00030000) /* bits 16-17 */ +#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK (0x00F00000) /* bits 20-23 */ +#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK (0xC0000000) /* bits 30-31 */ + +#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20) +#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT (4) +#define RX_RB_TIMEOUT (0x10) + +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) +#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000) + +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K (0x00010000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K (0x00020000) +#define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000) + +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) + + +/** + * Rx Shared Status Registers (RSSR) + * + * After stopping Rx DMA channel (writing 0 to FH_MEM_RCSR_CHNL0_CONFIG_REG), + * driver must poll FH_MEM_RSSR_RX_STATUS_REG until Rx channel is idle. + * + * Bit fields: + * 24: 1 = Channel 0 is idle + * + * FH_MEM_RSSR_SHARED_CTRL_REG and FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV contain + * default values that should not be altered by the driver. + */ #define FH_MEM_RSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xC40) #define FH_MEM_RSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) + #define FH_MEM_RSSR_SHARED_CTRL_REG (FH_MEM_RSSR_LOWER_BOUND) #define FH_MEM_RSSR_RX_STATUS_REG (FH_MEM_RSSR_LOWER_BOUND + 0x004) #define FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV (FH_MEM_RSSR_LOWER_BOUND + 0x008) -/* TCSR */ -#define IWL_FH_TCSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xD00) -#define IWL_FH_TCSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xE60) +#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000) -#define IWL_FH_TCSR_CHNL_NUM (7) + +/** + * Transmit DMA Channel Control/Status Registers (TCSR) + * + * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels + * supported in hardware (don't confuse these with the 16 Tx queues in DRAM, + * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes. + * + * To use a Tx DMA channel, driver must initialize its + * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl) with: + * + * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + * IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL + * + * All other bits should be 0. + * + * Bit fields: + * 31-30: Tx DMA channel enable: '00' off/pause, '01' pause at end of frame, + * '10' operate normally + * 29- 4: Reserved, set to "0" + * 3: Enable internal DMA requests (1, normal operation), disable (0) + * 2- 0: Reserved, set to "0" + */ +#define IWL_FH_TCSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xD00) +#define IWL_FH_TCSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xE60) + +/* Find Control/Status reg for given Tx DMA/FIFO channel */ #define IWL_FH_TCSR_CHNL_TX_CONFIG_REG(_chnl) \ (IWL_FH_TCSR_LOWER_BOUND + 0x20 * _chnl) -/* TSSR Area - Tx shared status registers */ -/* TSSR */ -#define IWL_FH_TSSR_LOWER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEA0) -#define IWL_FH_TSSR_UPPER_BOUND (IWL_FH_REGS_LOWER_BOUND + 0xEC0) - -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG (IWL_FH_TSSR_LOWER_BOUND + 0x008) -#define IWL_FH_TSSR_TX_STATUS_REG (IWL_FH_TSSR_LOWER_BOUND + 0x010) - -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) +#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) +#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_64B (0x00000000) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_256B (0x00000800) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_512B (0x00000C00) +#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) +#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000) +#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) +/** + * Tx Shared Status Registers (TSSR) + * + * After stopping Tx DMA channel (writing 0 to + * IWL_FH_TCSR_CHNL_TX_CONFIG_REG(chnl)), driver must poll + * IWL_FH_TSSR_TX_STATUS_REG until selected Tx channel is idle + * (channel's buffers empty | no pending requests). + * + * Bit fields: + * 31-24: 1 = Channel buffers empty (channel 7:0) + * 23-16: 1 = No pending requests (channel 7:0) + */ +#define IWL_FH_TSSR_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xEA0) +#define IWL_FH_TSSR_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xEC0) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define IWL_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) +#define IWL_FH_TSSR_TX_STATUS_REG (IWL_FH_TSSR_LOWER_BOUND + 0x010) #define IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) \ ((1 << (_chnl)) << 24) @@ -341,147 +1558,347 @@ union iwl_tx_power_dual_stream { (IWL_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_chnl) | \ IWL_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_chnl)) -/* TCSR: tx_config register values */ -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_ARC (0x00000002) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_NOINT (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD (0x00100000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_ENDTFD (0x00400000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_IFTFD (0x00800000) - -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE_EOF (0x40000000) -#define IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) - -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_EMPTY (0x00000000) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_WAIT (0x00002000) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00000003) - -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM (20) -#define IWL_FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX (12) - -/* RCSR: channel 0 rx_config register defines */ -#define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MASK (0xC0000000) /* bits 30-31 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MASK (0x00F00000) /* bits 20-23 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RB_SIZE_MASK (0x00030000) /* bits 16-17 */ -#define FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MASK (0x00008000) /* bit 15 */ -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MASK (0x00001000) /* bit 12 */ -#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MASK (0x00000FF0) /* bit 4-11 */ - -#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20) -#define FH_RCSR_RX_CONFIG_RB_SIZE_BITSHIFT (16) - -/* RCSR: rx_config register values */ -#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) -#define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) -#define FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL (0x80000000) - -#define IWL_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K (0x00000000) -/* RCSR channel 0 config register values */ -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) - -/* RSCSR: defs used in normal mode */ -#define FH_RSCSR_CHNL0_RBDCB_WPTR_MASK (0x00000FFF) /* bits 0-11 */ +/********************* START TX SCHEDULER *************************************/ +/** + * 4965 Tx Scheduler + * + * The Tx Scheduler selects the next frame to be transmitted, chosing TFDs + * (Transmit Frame Descriptors) from up to 16 circular Tx queues resident in + * host DRAM. It steers each frame's Tx command (which contains the frame + * data) into one of up to 7 prioritized Tx DMA FIFO channels within the + * device. A queue maps to only one (selectable by driver) Tx DMA channel, + * but one DMA channel may take input from several queues. + * + * Tx DMA channels have dedicated purposes. For 4965, they are used as follows: + * + * 0 -- EDCA BK (background) frames, lowest priority + * 1 -- EDCA BE (best effort) frames, normal priority + * 2 -- EDCA VI (video) frames, higher priority + * 3 -- EDCA VO (voice) and management frames, highest priority + * 4 -- Commands (e.g. RXON, etc.) + * 5 -- HCCA short frames + * 6 -- HCCA long frames + * 7 -- not used by driver (device-internal only) + * + * Driver should normally map queues 0-6 to Tx DMA/FIFO channels 0-6. + * In addition, driver can map queues 7-15 to Tx DMA/FIFO channels 0-3 to + * support 11n aggregation via EDCA DMA channels. + * + * The driver sets up each queue to work in one of two modes: + * + * 1) Scheduler-Ack, in which the scheduler automatically supports a + * block-ack (BA) window of up to 64 TFDs. In this mode, each queue + * contains TFDs for a unique combination of Recipient Address (RA) + * and Traffic Identifier (TID), that is, traffic of a given + * Quality-Of-Service (QOS) priority, destined for a single station. + * + * In scheduler-ack mode, the scheduler keeps track of the Tx status of + * each frame within the BA window, including whether it's been transmitted, + * and whether it's been acknowledged by the receiving station. The device + * automatically processes block-acks received from the receiving STA, + * and reschedules un-acked frames to be retransmitted (successful + * Tx completion may end up being out-of-order). + * + * The driver must maintain the queue's Byte Count table in host DRAM + * (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode. + * This mode does not support fragmentation. + * + * 2) FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order. + * The device may automatically retry Tx, but will retry only one frame + * at a time, until receiving ACK from receiving station, or reaching + * retry limit and giving up. + * + * The command queue (#4) 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: + * 1) Scheduler registers + * 2) Shared scheduler data base in internal 4956 SRAM + * 3) Shared data in host DRAM + * + * Initialization: + * + * When loading, driver should allocate memory for: + * 1) 16 TFD circular buffers, each with space for (typically) 256 TFDs. + * 2) 16 Byte Count circular buffers in 16 KBytes contiguous memory + * (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 driver can't issue commands!): + */ + +/** + * Max Tx window size is the max number of contiguous TFDs that the scheduler + * can keep track of at one time when creating block-ack chains of frames. + * Note that "64" matches the number of ack bits in a block-ack packet. + * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize + * SCD_CONTEXT_QUEUE_OFFSET(x) values. + */ #define SCD_WIN_SIZE 64 #define SCD_FRAME_LIMIT 64 -/* memory mapped registers */ +/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */ #define SCD_START_OFFSET 0xa02c00 +/* + * 4965 tells driver SRAM address for internal scheduler structs via this reg. + * Value is valid only after "Alive" response from uCode. + */ #define SCD_SRAM_BASE_ADDR (SCD_START_OFFSET + 0x0) + +/* + * Driver may need to update queue-empty bits after changing queue's + * write and read pointers (indexes) during (re-)initialization (i.e. when + * scheduler is not tracking what's happening). + * Bit fields: + * 31-16: Write mask -- 1: update empty bit, 0: don't change empty bit + * 15-00: Empty state, one for each queue -- 1: empty, 0: non-empty + * NOTE: This register is not used by Linux driver. + */ #define SCD_EMPTY_BITS (SCD_START_OFFSET + 0x4) + +/* + * Physical base address of array of byte count (BC) circular buffers (CBs). + * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode. + * This register points to BC CB for queue 0, must be on 1024-byte boundary. + * Others are spaced by 1024 bytes. + * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad. + * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff). + * Bit fields: + * 25-00: Byte Count CB physical address [35:10], must be 1024-byte aligned. + */ #define SCD_DRAM_BASE_ADDR (SCD_START_OFFSET + 0x10) -#define SCD_AIT (SCD_START_OFFSET + 0x18) -#define SCD_TXFACT (SCD_START_OFFSET + 0x1c) -#define SCD_QUEUE_WRPTR(x) (SCD_START_OFFSET + 0x24 + (x) * 4) -#define SCD_QUEUE_RDPTR(x) (SCD_START_OFFSET + 0x64 + (x) * 4) -#define SCD_SETQUEUENUM (SCD_START_OFFSET + 0xa4) -#define SCD_SET_TXSTAT_TXED (SCD_START_OFFSET + 0xa8) -#define SCD_SET_TXSTAT_DONE (SCD_START_OFFSET + 0xac) -#define SCD_SET_TXSTAT_NOT_SCHD (SCD_START_OFFSET + 0xb0) -#define SCD_DECREASE_CREDIT (SCD_START_OFFSET + 0xb4) -#define SCD_DECREASE_SCREDIT (SCD_START_OFFSET + 0xb8) -#define SCD_LOAD_CREDIT (SCD_START_OFFSET + 0xbc) -#define SCD_LOAD_SCREDIT (SCD_START_OFFSET + 0xc0) -#define SCD_BAR (SCD_START_OFFSET + 0xc4) -#define SCD_BAR_DW0 (SCD_START_OFFSET + 0xc8) -#define SCD_BAR_DW1 (SCD_START_OFFSET + 0xcc) -#define SCD_QUEUECHAIN_SEL (SCD_START_OFFSET + 0xd0) -#define SCD_QUERY_REQ (SCD_START_OFFSET + 0xd8) -#define SCD_QUERY_RES (SCD_START_OFFSET + 0xdc) -#define SCD_PENDING_FRAMES (SCD_START_OFFSET + 0xe0) -#define SCD_INTERRUPT_MASK (SCD_START_OFFSET + 0xe4) -#define SCD_INTERRUPT_THRESHOLD (SCD_START_OFFSET + 0xe8) -#define SCD_QUERY_MIN_FRAME_SIZE (SCD_START_OFFSET + 0x100) -#define SCD_QUEUE_STATUS_BITS(x) (SCD_START_OFFSET + 0x104 + (x) * 4) -/* SRAM structures */ -#define SCD_CONTEXT_DATA_OFFSET 0x380 -#define SCD_TX_STTS_BITMAP_OFFSET 0x400 -#define SCD_TRANSLATE_TBL_OFFSET 0x500 -#define SCD_CONTEXT_QUEUE_OFFSET(x) (SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) -#define SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ - ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) +/* + * Enables any/all Tx DMA/FIFO channels. + * Scheduler generates requests for only the active channels. + * Set this to 0xff to enable all 8 channels (normal usage). + * Bit fields: + * 7- 0: Enable (1), disable (0), one bit for each channel 0-7 + */ +#define SCD_TXFACT (SCD_START_OFFSET + 0x1c) +/* Mask to enable contiguous Tx DMA/FIFO channels between "lo" and "hi". */ #define SCD_TXFACT_REG_TXFIFO_MASK(lo, hi) \ ((1<<(hi))|((1<<(hi))-(1<<(lo)))) +/* + * Queue (x) Write Pointers (indexes, really!), one for each Tx queue. + * Initialized and updated by driver as new TFDs are added to queue. + * NOTE: If using Block Ack, index must correspond to frame's + * Start Sequence Number; index = (SSN & 0xff) + * NOTE: Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses? + */ +#define SCD_QUEUE_WRPTR(x) (SCD_START_OFFSET + 0x24 + (x) * 4) -#define SCD_MODE_REG_BIT_SEARCH_MODE (1<<0) -#define SCD_MODE_REG_BIT_SBYP_MODE (1<<1) +/* + * Queue (x) Read Pointers (indexes, really!), one for each Tx queue. + * For FIFO mode, index indicates next frame to transmit. + * For Scheduler-ACK mode, index indicates first frame in Tx window. + * Initialized by driver, updated by scheduler. + */ +#define SCD_QUEUE_RDPTR(x) (SCD_START_OFFSET + 0x64 + (x) * 4) -#define SCD_TXFIFO_POS_TID (0) -#define SCD_TXFIFO_POS_RA (4) +/* + * Select which queues work in chain mode (1) vs. not (0). + * Use chain mode to build chains of aggregated frames. + * Bit fields: + * 31-16: Reserved + * 15-00: Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time + * NOTE: If driver sets up queue for chain mode, it should be also set up + * Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x). + */ +#define SCD_QUEUECHAIN_SEL (SCD_START_OFFSET + 0xd0) + +/* + * Select which queues interrupt driver when scheduler increments + * a queue's read pointer (index). + * Bit fields: + * 31-16: Reserved + * 15-00: Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled + * NOTE: This functionality is apparently a no-op; driver relies on interrupts + * from Rx queue to read Tx command responses and update Tx queues. + */ +#define SCD_INTERRUPT_MASK (SCD_START_OFFSET + 0xe4) + +/* + * Queue search status registers. One for each queue. + * Sets up queue mode and assigns queue to Tx DMA channel. + * Bit fields: + * 19-10: Write mask/enable bits for bits 0-9 + * 9: Driver should init to "0" + * 8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0). + * Driver should init to "1" for aggregation mode, or "0" otherwise. + * 7-6: Driver should init to "0" + * 5: Window Size Left; indicates whether scheduler can request + * another TFD, based on window size, etc. Driver should init + * this bit to "1" for aggregation mode, or "0" for non-agg. + * 4-1: Tx FIFO to use (range 0-7). + * 0: Queue is active (1), not active (0). + * Other bits should be written as "0" + * + * NOTE: If enabling Scheduler-ACK mode, chain mode should also be enabled + * via SCD_QUEUECHAIN_SEL. + */ +#define SCD_QUEUE_STATUS_BITS(x) (SCD_START_OFFSET + 0x104 + (x) * 4) + +/* Bit field positions */ #define SCD_QUEUE_STTS_REG_POS_ACTIVE (0) #define SCD_QUEUE_STTS_REG_POS_TXF (1) #define SCD_QUEUE_STTS_REG_POS_WSL (5) #define SCD_QUEUE_STTS_REG_POS_SCD_ACK (8) + +/* Write masks */ #define SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN (10) #define SCD_QUEUE_STTS_REG_MSK (0x0007FC00) -#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) +/** + * 4965 internal SRAM structures for scheduler, shared with driver ... + * + * Driver should clear and initialize the following areas after receiving + * "Alive" response from 4965 uCode, i.e. after initial + * uCode load, or after a uCode load done for error recovery: + * + * SCD_CONTEXT_DATA_OFFSET (size 128 bytes) + * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes) + * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes) + * + * Driver accesses SRAM via HBUS_TARG_MEM_* registers. + * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR. + * All OFFSET values must be added to this base address. + */ + +/* + * Queue context. One 8-byte entry for each of 16 queues. + * + * Driver should clear this entire area (size 0x80) to 0 after receiving + * "Alive" notification from uCode. Additionally, driver should init + * each queue's entry as follows: + * + * LS Dword bit fields: + * 0-06: Max Tx window size for Scheduler-ACK. Driver should init to 64. + * + * MS Dword bit fields: + * 16-22: Frame limit. Driver should init to 10 (0xa). + * + * Driver should init all other bits to 0. + * + * Init must be done after driver receives "Alive" response from 4965 uCode, + * and when setting up queue for aggregation. + */ +#define SCD_CONTEXT_DATA_OFFSET 0x380 +#define SCD_CONTEXT_QUEUE_OFFSET(x) (SCD_CONTEXT_DATA_OFFSET + ((x) * 8)) #define SCD_QUEUE_CTX_REG1_WIN_SIZE_POS (0) #define SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK (0x0000007F) -#define SCD_QUEUE_CTX_REG1_CREDIT_POS (8) -#define SCD_QUEUE_CTX_REG1_CREDIT_MSK (0x00FFFF00) -#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_POS (24) -#define SCD_QUEUE_CTX_REG1_SUPER_CREDIT_MSK (0xFF000000) #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) #define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) -#define CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R (0x00000010) -#define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER (0x00000C00) -#define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI (0x00000100) -#define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI (0x00000200) +/* + * Tx Status Bitmap + * + * Driver should clear this entire area (size 0x100) to 0 after receiving + * "Alive" notification from uCode. Area is used only by device itself; + * no other support (besides clearing) is required from driver. + */ +#define SCD_TX_STTS_BITMAP_OFFSET 0x400 -static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) +/* + * RAxTID to queue translation mapping. + * + * When queue is in Scheduler-ACK mode, frames placed in a that queue must be + * for only one combination of receiver address (RA) and traffic ID (TID), i.e. + * one QOS priority level destined for one station (for this wireless link, + * not final destination). The SCD_TRANSLATE_TABLE area provides 16 16-bit + * mappings, one for each of the 16 queues. If queue is not in Scheduler-ACK + * mode, the device ignores the mapping value. + * + * Bit fields, for each 16-bit map: + * 15-9: Reserved, set to 0 + * 8-4: Index into device's station table for recipient station + * 3-0: Traffic ID (tid), range 0-15 + * + * Driver should clear this entire area (size 32 bytes) to 0 after receiving + * "Alive" notification from uCode. To update a 16-bit map value, driver + * must read a dword-aligned value from device SRAM, replace the 16-bit map + * value of interest, and write the dword value back into device SRAM. + */ +#define SCD_TRANSLATE_TBL_OFFSET 0x500 + +/* Find translation table dword to read/write for given queue */ +#define SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ + ((SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc) + +#define SCD_TXFIFO_POS_TID (0) +#define SCD_TXFIFO_POS_RA (4) +#define SCD_QUEUE_RA_TID_MAP_RATID_MSK (0x01FF) + +/*********************** END TX SCHEDULER *************************************/ + +static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags) { return le32_to_cpu(rate_n_flags) & 0xFF; } -static inline u16 iwl_hw_get_rate_n_flags(__le32 rate_n_flags) +static inline u16 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags) { return le32_to_cpu(rate_n_flags) & 0xFFFF; } -static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u16 flags) +static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) { return cpu_to_le32(flags|(u16)rate); } -struct iwl_tfd_frame_data { + +/** + * Tx/Rx Queues + * + * Most communication between driver and 4965 is via queues of data buffers. + * For example, all commands that the driver issues to device's embedded + * controller (uCode) are via the command queue (one of the Tx queues). All + * uCode command responses/replies/notifications, including Rx frames, are + * conveyed from uCode to driver via the Rx queue. + * + * Most support for these queues, including handshake support, resides in + * structures in host DRAM, shared between the driver and the device. When + * allocating this memory, the driver must make sure that data written by + * the host CPU updates DRAM immediately (and does not get "stuck" in CPU's + * cache memory), so DRAM and cache are consistent, and the device can + * immediately see changes made by the driver. + * + * 4965 supports up to 16 DRAM-based Tx queues, and services these queues via + * up to 7 DMA channels (FIFOs). Each Tx queue is supported by a circular array + * in DRAM containing 256 Transmit Frame Descriptors (TFDs). + */ +#define IWL4965_MAX_WIN_SIZE 64 +#define IWL4965_QUEUE_SIZE 256 +#define IWL4965_NUM_FIFOS 7 +#define IWL_MAX_NUM_QUEUES 16 + + +/** + * struct iwl4965_tfd_frame_data + * + * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. + * Each buffer must be on dword boundary. + * Up to 10 iwl_tfd_frame_data structures, describing up to 20 buffers, + * may be filled within a TFD (iwl_tfd_frame). + * + * Bit fields in tb1_addr: + * 31- 0: Tx buffer 1 address bits [31:0] + * + * Bit fields in val1: + * 31-16: Tx buffer 2 address bits [15:0] + * 15- 4: Tx buffer 1 length (bytes) + * 3- 0: Tx buffer 1 address bits [32:32] + * + * Bit fields in val2: + * 31-20: Tx buffer 2 length (bytes) + * 19- 0: Tx buffer 2 address bits [35:16] + */ +struct iwl4965_tfd_frame_data { __le32 tb1_addr; __le32 val1; @@ -509,7 +1926,36 @@ struct iwl_tfd_frame_data { #define IWL_tb2_len_SYM val2 } __attribute__ ((packed)); -struct iwl_tfd_frame { + +/** + * struct iwl4965_tfd_frame + * + * Transmit Frame Descriptor (TFD) + * + * 4965 supports up to 16 Tx queues resident in host DRAM. + * Each Tx queue uses a circular buffer of 256 TFDs stored in host DRAM. + * Both driver and device share these circular buffers, each of which must be + * contiguous 256 TFDs x 128 bytes-per-TFD = 32 KBytes for 4965. + * + * Driver must indicate the physical address of the base of each + * circular buffer via the 4965's FH_MEM_CBBC_QUEUE registers. + * + * Each TFD contains pointer/size information for up to 20 data buffers + * in host DRAM. These buffers collectively contain the (one) frame described + * by the TFD. Each buffer must be a single contiguous block of memory within + * itself, but buffers may be scattered in host DRAM. Each buffer has max size + * of (4K - 4). The 4965 concatenates all of a TFD's buffers into a single + * Tx frame, up to 8 KBytes in size. + * + * Bit fields in the control dword (val0): + * 31-30: # dwords (0-3) of padding required at end of frame for 16-byte bound + * 29: reserved + * 28-24: # Transmit Buffer Descriptors in TFD + * 23- 0: reserved + * + * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. + */ +struct iwl4965_tfd_frame { __le32 val0; /* __le32 rsvd1:24; */ /* __le32 num_tbs:5; */ @@ -518,15 +1964,20 @@ struct iwl_tfd_frame { #define IWL_num_tbs_SYM val0 /* __le32 rsvd2:1; */ /* __le32 padding:2; */ - struct iwl_tfd_frame_data pa[10]; + struct iwl4965_tfd_frame_data pa[10]; __le32 reserved; } __attribute__ ((packed)); -#define IWL4965_MAX_WIN_SIZE 64 -#define IWL4965_QUEUE_SIZE 256 -#define IWL4965_NUM_FIFOS 7 -#define IWL_MAX_NUM_QUEUES 16 +/** + * struct iwl4965_queue_byte_cnt_entry + * + * Byte Count Table Entry + * + * Bit fields: + * 15-12: reserved + * 11- 0: total to-be-transmitted byte count of frame (does not include command) + */ struct iwl4965_queue_byte_cnt_entry { __le16 val; /* __le16 byte_cnt:12; */ @@ -536,6 +1987,25 @@ struct iwl4965_queue_byte_cnt_entry { /* __le16 rsvd:4; */ } __attribute__ ((packed)); + +/** + * struct iwl4965_sched_queue_byte_cnt_tbl + * + * Byte Count table + * + * Each Tx queue uses a byte-count table containing 320 entries: + * one 16-bit entry for each of 256 TFDs, plus an additional 64 entries that + * duplicate the first 64 entries (to avoid wrap-around within a Tx window; + * max Tx window is 64 TFDs). + * + * When driver sets up a new TFD, it must also enter the total byte count + * of the frame to be transmitted into the corresponding entry in the byte + * count table for the chosen Tx queue. If the TFD index is 0-63, the driver + * must duplicate the byte count entry in corresponding index 256-319. + * + * "dont_care" padding puts each byte count table on a 1024-byte boundary; + * 4965 assumes tables are separated by 1024 bytes. + */ struct iwl4965_sched_queue_byte_cnt_tbl { struct iwl4965_queue_byte_cnt_entry tfd_offset[IWL4965_QUEUE_SIZE + IWL4965_MAX_WIN_SIZE]; @@ -544,9 +2014,31 @@ struct iwl4965_sched_queue_byte_cnt_tbl { sizeof(__le16)]; } __attribute__ ((packed)); -/* Base physical address of iwl_shared is provided to SCD_DRAM_BASE_ADDR - * and &iwl_shared.val0 is provided to FH_RSCSR_CHNL0_STTS_WPTR_REG */ -struct iwl_shared { + +/** + * struct iwl4965_shared - handshake area for Tx and Rx + * + * For convenience in allocating memory, this structure combines 2 areas of + * DRAM which must be shared between driver and 4965. These do not need to + * be combined, if better allocation would result from keeping them separate: + * + * 1) The Tx byte count tables occupy 1024 bytes each (16 KBytes total for + * 16 queues). Driver uses SCD_DRAM_BASE_ADDR to tell 4965 where to find + * the first of these tables. 4965 assumes tables are 1024 bytes apart. + * + * 2) The Rx status (val0 and val1) occupies only 8 bytes. Driver uses + * FH_RSCSR_CHNL0_STTS_WPTR_REG to tell 4965 where to find this area. + * Driver reads val0 to determine the latest Receive Buffer Descriptor (RBD) + * that has been filled by the 4965. + * + * Bit fields val0: + * 31-12: Not used + * 11- 0: Index of last filled Rx buffer descriptor (4965 writes, driver reads) + * + * Bit fields val1: + * 31- 0: Not used + */ +struct iwl4965_shared { struct iwl4965_sched_queue_byte_cnt_tbl queues_byte_cnt_tbls[IWL_MAX_NUM_QUEUES]; __le32 val0; @@ -578,4 +2070,4 @@ struct iwl_shared { __le32 padding2; } __attribute__ ((packed)); -#endif /* __iwl_4965_hw_h__ */ +#endif /* __iwl4965_4965_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-io.h b/drivers/net/wireless/iwlwifi/iwl-4965-io.h new file mode 100644 index 0000000..34a0b57 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-4965-io.h @@ -0,0 +1,431 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project. + * + * 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: + * James P. Ketrenos + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#ifndef __iwl4965_io_h__ +#define __iwl4965_io_h__ + +#include + +#include "iwl-4965-debug.h" + +/* + * IO, register, and NIC memory access functions + * + * NOTE on naming convention and macro usage for these + * + * A single _ prefix before a an access function means that no state + * check or debug information is printed when that function is called. + * + * A double __ prefix before an access function means that state is checked + * and the current line number is printed in addition to any other debug output. + * + * The non-prefixed name is the #define that maps the caller into a + * #define that provides the caller's __LINE__ to the double prefix version. + * + * If you wish to call the function without any debug or state checking, + * you should use the single _ prefix version (as is used by dependent IO + * routines, for example _iwl4965_read_direct32 calls the non-check version of + * _iwl4965_read32.) + * + * These declarations are *extremely* useful in quickly isolating code deltas + * which result in misconfiguring of the hardware I/O. In combination with + * git-bisect and the IO debug level you can quickly determine the specific + * commit which breaks the IO sequence to the hardware. + * + */ + +#define _iwl4965_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_write32(const char *f, u32 l, struct iwl4965_priv *iwl, + u32 ofs, u32 val) +{ + IWL_DEBUG_IO("write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l); + _iwl4965_write32(iwl, ofs, val); +} +#define iwl4965_write32(iwl, ofs, val) \ + __iwl4965_write32(__FILE__, __LINE__, iwl, ofs, val) +#else +#define iwl4965_write32(iwl, ofs, val) _iwl4965_write32(iwl, ofs, val) +#endif + +#define _iwl4965_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) +#ifdef CONFIG_IWL4965_DEBUG +static inline u32 __iwl4965_read32(char *f, u32 l, struct iwl4965_priv *iwl, u32 ofs) +{ + IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); + return _iwl4965_read32(iwl, ofs); +} +#define iwl4965_read32(iwl, ofs) __iwl4965_read32(__FILE__, __LINE__, iwl, ofs) +#else +#define iwl4965_read32(p, o) _iwl4965_read32(p, o) +#endif + +static inline int _iwl4965_poll_bit(struct iwl4965_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int i = 0; + + do { + if ((_iwl4965_read32(priv, addr) & mask) == (bits & mask)) + return i; + mdelay(10); + i += 10; + } while (i < timeout); + + return -ETIMEDOUT; +} +#ifdef CONFIG_IWL4965_DEBUG +static inline int __iwl4965_poll_bit(const char *f, u32 l, + struct iwl4965_priv *priv, u32 addr, + u32 bits, u32 mask, int timeout) +{ + int ret = _iwl4965_poll_bit(priv, addr, bits, mask, timeout); + if (unlikely(ret == -ETIMEDOUT)) + IWL_DEBUG_IO + ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", + addr, bits, mask, f, l); + else + IWL_DEBUG_IO + ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", + addr, bits, mask, ret, f, l); + return ret; +} +#define iwl4965_poll_bit(iwl, addr, bits, mask, timeout) \ + __iwl4965_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) +#else +#define iwl4965_poll_bit(p, a, b, m, t) _iwl4965_poll_bit(p, a, b, m, t) +#endif + +static inline void _iwl4965_set_bit(struct iwl4965_priv *priv, u32 reg, u32 mask) +{ + _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) | mask); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_set_bit(const char *f, u32 l, + struct iwl4965_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl4965_read32(priv, reg) | mask; + IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); + _iwl4965_write32(priv, reg, val); +} +#define iwl4965_set_bit(p, r, m) __iwl4965_set_bit(__FILE__, __LINE__, p, r, m) +#else +#define iwl4965_set_bit(p, r, m) _iwl4965_set_bit(p, r, m) +#endif + +static inline void _iwl4965_clear_bit(struct iwl4965_priv *priv, u32 reg, u32 mask) +{ + _iwl4965_write32(priv, reg, _iwl4965_read32(priv, reg) & ~mask); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_clear_bit(const char *f, u32 l, + struct iwl4965_priv *priv, u32 reg, u32 mask) +{ + u32 val = _iwl4965_read32(priv, reg) & ~mask; + IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); + _iwl4965_write32(priv, reg, val); +} +#define iwl4965_clear_bit(p, r, m) __iwl4965_clear_bit(__FILE__, __LINE__, p, r, m) +#else +#define iwl4965_clear_bit(p, r, m) _iwl4965_clear_bit(p, r, m) +#endif + +static inline int _iwl4965_grab_nic_access(struct iwl4965_priv *priv) +{ + int ret; + u32 gp_ctl; + +#ifdef CONFIG_IWL4965_DEBUG + if (atomic_read(&priv->restrict_refcnt)) + return 0; +#endif + if (test_bit(STATUS_RF_KILL_HW, &priv->status) || + test_bit(STATUS_RF_KILL_SW, &priv->status)) { + IWL_WARNING("WARNING: Requesting MAC access during RFKILL " + "wakes up NIC\n"); + + /* 10 msec allows time for NIC to complete its data save */ + gp_ctl = _iwl4965_read32(priv, CSR_GP_CNTRL); + if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) { + IWL_DEBUG_RF_KILL("Wait for complete power-down, " + "gpctl = 0x%08x\n", gp_ctl); + mdelay(10); + } else + IWL_DEBUG_RF_KILL("power-down complete, " + "gpctl = 0x%08x\n", gp_ctl); + } + + /* this bit wakes up the NIC */ + _iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + ret = _iwl4965_poll_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, + (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | + CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50); + if (ret < 0) { + IWL_ERROR("MAC is in deep sleep!\n"); + return -EIO; + } + +#ifdef CONFIG_IWL4965_DEBUG + atomic_inc(&priv->restrict_refcnt); +#endif + return 0; +} + +#ifdef CONFIG_IWL4965_DEBUG +static inline int __iwl4965_grab_nic_access(const char *f, u32 l, + struct iwl4965_priv *priv) +{ + if (atomic_read(&priv->restrict_refcnt)) + IWL_DEBUG_INFO("Grabbing access while already held at " + "line %d.\n", l); + + IWL_DEBUG_IO("grabbing nic access - %s %d\n", f, l); + return _iwl4965_grab_nic_access(priv); +} +#define iwl4965_grab_nic_access(priv) \ + __iwl4965_grab_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl4965_grab_nic_access(priv) \ + _iwl4965_grab_nic_access(priv) +#endif + +static inline void _iwl4965_release_nic_access(struct iwl4965_priv *priv) +{ +#ifdef CONFIG_IWL4965_DEBUG + if (atomic_dec_and_test(&priv->restrict_refcnt)) +#endif + _iwl4965_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_release_nic_access(const char *f, u32 l, + struct iwl4965_priv *priv) +{ + if (atomic_read(&priv->restrict_refcnt) <= 0) + IWL_ERROR("Release unheld nic access at line %d.\n", l); + + IWL_DEBUG_IO("releasing nic access - %s %d\n", f, l); + _iwl4965_release_nic_access(priv); +} +#define iwl4965_release_nic_access(priv) \ + __iwl4965_release_nic_access(__FILE__, __LINE__, priv) +#else +#define iwl4965_release_nic_access(priv) \ + _iwl4965_release_nic_access(priv) +#endif + +static inline u32 _iwl4965_read_direct32(struct iwl4965_priv *priv, u32 reg) +{ + return _iwl4965_read32(priv, reg); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline u32 __iwl4965_read_direct32(const char *f, u32 l, + struct iwl4965_priv *priv, u32 reg) +{ + u32 value = _iwl4965_read_direct32(priv, reg); + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from %s %d\n", f, l); + IWL_DEBUG_IO("read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value, + f, l); + return value; +} +#define iwl4965_read_direct32(priv, reg) \ + __iwl4965_read_direct32(__FILE__, __LINE__, priv, reg) +#else +#define iwl4965_read_direct32 _iwl4965_read_direct32 +#endif + +static inline void _iwl4965_write_direct32(struct iwl4965_priv *priv, + u32 reg, u32 value) +{ + _iwl4965_write32(priv, reg, value); +} +#ifdef CONFIG_IWL4965_DEBUG +static void __iwl4965_write_direct32(u32 line, + struct iwl4965_priv *priv, u32 reg, u32 value) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + _iwl4965_write_direct32(priv, reg, value); +} +#define iwl4965_write_direct32(priv, reg, value) \ + __iwl4965_write_direct32(__LINE__, priv, reg, value) +#else +#define iwl4965_write_direct32 _iwl4965_write_direct32 +#endif + +static inline void iwl4965_write_reg_buf(struct iwl4965_priv *priv, + u32 reg, u32 len, u32 *values) +{ + u32 count = sizeof(u32); + + if ((priv != NULL) && (values != NULL)) { + for (; 0 < len; len -= count, reg += count, values++) + _iwl4965_write_direct32(priv, reg, *values); + } +} + +static inline int _iwl4965_poll_direct_bit(struct iwl4965_priv *priv, + u32 addr, u32 mask, int timeout) +{ + int i = 0; + + do { + if ((_iwl4965_read_direct32(priv, addr) & mask) == mask) + return i; + mdelay(10); + i += 10; + } while (i < timeout); + + return -ETIMEDOUT; +} + +#ifdef CONFIG_IWL4965_DEBUG +static inline int __iwl4965_poll_direct_bit(const char *f, u32 l, + struct iwl4965_priv *priv, + u32 addr, u32 mask, int timeout) +{ + int ret = _iwl4965_poll_direct_bit(priv, addr, mask, timeout); + + if (unlikely(ret == -ETIMEDOUT)) + IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) - " + "timedout - %s %d\n", addr, mask, f, l); + else + IWL_DEBUG_IO("poll_direct_bit(0x%08X, 0x%08X) = 0x%08X " + "- %s %d\n", addr, mask, ret, f, l); + return ret; +} +#define iwl4965_poll_direct_bit(iwl, addr, mask, timeout) \ + __iwl4965_poll_direct_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) +#else +#define iwl4965_poll_direct_bit _iwl4965_poll_direct_bit +#endif + +static inline u32 _iwl4965_read_prph(struct iwl4965_priv *priv, u32 reg) +{ + _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + return _iwl4965_read_direct32(priv, HBUS_TARG_PRPH_RDAT); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline u32 __iwl4965_read_prph(u32 line, struct iwl4965_priv *priv, u32 reg) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + return _iwl4965_read_prph(priv, reg); +} + +#define iwl4965_read_prph(priv, reg) \ + __iwl4965_read_prph(__LINE__, priv, reg) +#else +#define iwl4965_read_prph _iwl4965_read_prph +#endif + +static inline void _iwl4965_write_prph(struct iwl4965_priv *priv, + u32 addr, u32 val) +{ + _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WADDR, + ((addr & 0x0000FFFF) | (3 << 24))); + _iwl4965_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val); +} +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_write_prph(u32 line, struct iwl4965_priv *priv, + u32 addr, u32 val) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access from line %d\n", line); + _iwl4965_write_prph(priv, addr, val); +} + +#define iwl4965_write_prph(priv, addr, val) \ + __iwl4965_write_prph(__LINE__, priv, addr, val); +#else +#define iwl4965_write_prph _iwl4965_write_prph +#endif + +#define _iwl4965_set_bits_prph(priv, reg, mask) \ + _iwl4965_write_prph(priv, reg, (_iwl4965_read_prph(priv, reg) | mask)) +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_set_bits_prph(u32 line, struct iwl4965_priv *priv, + u32 reg, u32 mask) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + + _iwl4965_set_bits_prph(priv, reg, mask); +} +#define iwl4965_set_bits_prph(priv, reg, mask) \ + __iwl4965_set_bits_prph(__LINE__, priv, reg, mask) +#else +#define iwl4965_set_bits_prph _iwl4965_set_bits_prph +#endif + +#define _iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \ + _iwl4965_write_prph(priv, reg, ((_iwl4965_read_prph(priv, reg) & mask) | bits)) + +#ifdef CONFIG_IWL4965_DEBUG +static inline void __iwl4965_set_bits_mask_prph(u32 line, + struct iwl4965_priv *priv, u32 reg, u32 bits, u32 mask) +{ + if (!atomic_read(&priv->restrict_refcnt)) + IWL_ERROR("Nic access not held from line %d\n", line); + _iwl4965_set_bits_mask_prph(priv, reg, bits, mask); +} +#define iwl4965_set_bits_mask_prph(priv, reg, bits, mask) \ + __iwl4965_set_bits_mask_prph(__LINE__, priv, reg, bits, mask) +#else +#define iwl4965_set_bits_mask_prph _iwl4965_set_bits_mask_prph +#endif + +static inline void iwl4965_clear_bits_prph(struct iwl4965_priv + *priv, u32 reg, u32 mask) +{ + u32 val = _iwl4965_read_prph(priv, reg); + _iwl4965_write_prph(priv, reg, (val & ~mask)); +} + +static inline u32 iwl4965_read_targ_mem(struct iwl4965_priv *priv, u32 addr) +{ + iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr); + return iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT); +} + +static inline void iwl4965_write_targ_mem(struct iwl4965_priv *priv, u32 addr, u32 val) +{ + iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, val); +} + +static inline void iwl4965_write_targ_mem_buf(struct iwl4965_priv *priv, u32 addr, + u32 len, u32 *values) +{ + iwl4965_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr); + for (; 0 < len; len -= sizeof(u32), values++) + iwl4965_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values); +} +#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 8dc78c0..60fc9ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -36,11 +36,9 @@ #include -#define IWL 4965 - #include "../net/mac80211/ieee80211_rate.h" -#include "iwlwifi.h" +#include "iwl-4965.h" #include "iwl-helpers.h" #define RS_NAME "iwl-4965-rs" @@ -49,13 +47,12 @@ #define IWL_NUMBER_TRY 1 #define IWL_HT_NUMBER_TRY 3 -#define IWL_RATE_MAX_WINDOW 62 -#define IWL_RATE_HIGH_TH 10880 -#define IWL_RATE_MIN_FAILURE_TH 6 -#define IWL_RATE_MIN_SUCCESS_TH 8 -#define IWL_RATE_DECREASE_TH 1920 -#define IWL_RATE_INCREASE_TH 8960 -#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) /*2 seconds */ +#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ +#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */ +#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */ + +/* max time to accum history 2 seconds */ +#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) static u8 rs_ht_to_legacy[] = { IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX, @@ -67,83 +64,109 @@ static u8 rs_ht_to_legacy[] = { IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX }; -struct iwl_rate { +struct iwl4965_rate { u32 rate_n_flags; } __attribute__ ((packed)); -struct iwl_rate_scale_data { - u64 data; - s32 success_counter; - s32 success_ratio; - s32 counter; - s32 average_tpt; +/** + * struct iwl4965_rate_scale_data -- tx success history for one rate + */ +struct iwl4965_rate_scale_data { + u64 data; /* bitmap of successful frames */ + s32 success_counter; /* number of frames successful */ + s32 success_ratio; /* per-cent * 128 */ + s32 counter; /* number of frames attempted */ + s32 average_tpt; /* success ratio * expected throughput */ unsigned long stamp; }; -struct iwl_scale_tbl_info { - enum iwl_table_type lq_type; - enum iwl_antenna_type antenna_type; - u8 is_SGI; - u8 is_fat; - u8 is_dup; - u8 action; - s32 *expected_tpt; - struct iwl_rate current_rate; - struct iwl_rate_scale_data win[IWL_RATE_COUNT]; +/** + * struct iwl4965_scale_tbl_info -- tx params and success history for all rates + * + * There are two of these in struct iwl_rate_scale_priv, + * one for "active", and one for "search". + */ +struct iwl4965_scale_tbl_info { + enum iwl4965_table_type lq_type; + enum iwl4965_antenna_type antenna_type; + u8 is_SGI; /* 1 = short guard interval */ + u8 is_fat; /* 1 = 40 MHz channel width */ + u8 is_dup; /* 1 = duplicated data streams */ + u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ + s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ + struct iwl4965_rate current_rate; /* rate_n_flags, uCode API format */ + struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ }; -struct iwl_rate_scale_priv { - u8 active_tbl; - u8 enable_counter; - u8 stay_in_tbl; - u8 search_better_tbl; +/** + * struct iwl_rate_scale_priv -- driver's rate scaling private structure + * + * Pointer to this gets passed back and forth between driver and mac80211. + */ +struct iwl4965_rate_scale_priv { + u8 active_tbl; /* index of active table, range 0-1 */ + u8 enable_counter; /* indicates HT mode */ + u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */ + u8 search_better_tbl; /* 1: currently trying alternate mode */ s32 last_tpt; + + /* The following determine when to search for a new mode */ u32 table_count_limit; - u32 max_failure_limit; - u32 max_success_limit; + u32 max_failure_limit; /* # failed frames before new search */ + u32 max_success_limit; /* # successful frames before new search */ u32 table_count; - u32 total_failed; - u32 total_success; - u32 flush_timer; - u8 action_counter; + u32 total_failed; /* total failed frames, any/all rates */ + u32 total_success; /* total successful frames, any/all rates */ + u32 flush_timer; /* time staying in mode before new search */ + + u8 action_counter; /* # mode-switch actions tried */ u8 antenna; u8 valid_antenna; u8 is_green; u8 is_dup; u8 phymode; u8 ibss_sta_added; + + /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ u32 supp_rates; u16 active_rate; u16 active_siso_rate; u16 active_mimo_rate; u16 active_rate_basic; - struct iwl_link_quality_cmd lq; - struct iwl_scale_tbl_info lq_info[LQ_SIZE]; + + struct iwl4965_link_quality_cmd lq; + struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *rs_sta_dbgfs_scale_table_file; struct dentry *rs_sta_dbgfs_stats_table_file; - struct iwl_rate dbg_fixed; - struct iwl_priv *drv; + struct iwl4965_rate dbg_fixed; + struct iwl4965_priv *drv; #endif }; -static void rs_rate_scale_perform(struct iwl_priv *priv, +static void rs_rate_scale_perform(struct iwl4965_priv *priv, struct net_device *dev, struct ieee80211_hdr *hdr, struct sta_info *sta); -static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, - struct iwl_rate *tx_mcs, - struct iwl_link_quality_cmd *tbl); +static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data, + struct iwl4965_rate *tx_mcs, + struct iwl4965_link_quality_cmd *tbl); #ifdef CONFIG_MAC80211_DEBUGFS -static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv, - struct iwl_rate *mcs, int index); +static void rs_dbgfs_set_mcs(struct iwl4965_rate_scale_priv *rs_priv, + struct iwl4965_rate *mcs, int index); #else -static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv, - struct iwl_rate *mcs, int index) +static void rs_dbgfs_set_mcs(struct iwl4965_rate_scale_priv *rs_priv, + struct iwl4965_rate *mcs, int index) {} #endif + +/* + * Expected throughput metrics for following rates: + * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits + * "G" is the only table that supports CCK (the first 4 rates). + */ static s32 expected_tpt_A[IWL_RATE_COUNT] = { 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 }; @@ -184,36 +207,34 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = { 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 }; -static int iwl_lq_sync_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, struct sk_buff *skb) +static int iwl4965_lq_sync_callback(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct sk_buff *skb) { /*We didn't cache the SKB; let the caller free it */ return 1; } -static inline u8 iwl_rate_get_rate(u32 rate_n_flags) +static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) { return (u8)(rate_n_flags & 0xFF); } -static int rs_send_lq_cmd(struct iwl_priv *priv, - struct iwl_link_quality_cmd *lq, u8 flags) +static int rs_send_lq_cmd(struct iwl4965_priv *priv, + struct iwl4965_link_quality_cmd *lq, u8 flags) { -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG int i; #endif - int rc = -1; - - struct iwl_host_cmd cmd = { + struct iwl4965_host_cmd cmd = { .id = REPLY_TX_LINK_QUALITY_CMD, - .len = sizeof(struct iwl_link_quality_cmd), + .len = sizeof(struct iwl4965_link_quality_cmd), .meta.flags = flags, .data = lq, }; if ((lq->sta_id == 0xFF) && (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)) - return rc; + return -EINVAL; if (lq->sta_id == 0xFF) lq->sta_id = IWL_AP_ID; @@ -222,23 +243,23 @@ static int rs_send_lq_cmd(struct iwl_priv *priv, IWL_DEBUG_RATE("lq dta 0x%X 0x%X\n", lq->general_params.single_stream_ant_msk, lq->general_params.dual_stream_ant_msk); -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) IWL_DEBUG_RATE("lq index %d 0x%X\n", i, lq->rs_table[i].rate_n_flags); #endif if (flags & CMD_ASYNC) - cmd.meta.u.callback = iwl_lq_sync_callback; + cmd.meta.u.callback = iwl4965_lq_sync_callback; - if (iwl_is_associated(priv) && priv->assoc_station_added && + if (iwl4965_is_associated(priv) && priv->assoc_station_added && priv->lq_mngr.lq_ready) - rc = iwl_send_cmd(priv, &cmd); + return iwl4965_send_cmd(priv, &cmd); - return rc; + return 0; } -static int rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) +static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window) { window->data = 0; window->success_counter = 0; @@ -246,29 +267,38 @@ static int rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) window->counter = 0; window->average_tpt = IWL_INVALID_VALUE; window->stamp = 0; - - return 0; } -static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, +/** + * rs_collect_tx_data - Update the success/failure sliding window + * + * We keep a sliding window of the last 62 packets transmitted + * at this rate. window->data contains the bitmask of successful + * packets. + */ +static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, int scale_index, s32 tpt, u32 status) { - int rc = 0; - struct iwl_rate_scale_data *window = NULL; + struct iwl4965_rate_scale_data *window = NULL; u64 mask; u8 win_size = IWL_RATE_MAX_WINDOW; s32 fail_count; - if (scale_index < 0) - return -1; - - if (scale_index >= IWL_RATE_COUNT) - return -1; + if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) + return -EINVAL; + /* Select data for current tx bit rate */ window = &(windows[scale_index]); + /* + * Keep track of only the latest 62 tx frame attempts in this rate's + * history window; anything older isn't really relevant any more. + * If we have filled up the sliding window, drop the oldest attempt; + * if the oldest attempt (highest bit in bitmap) shows "success", + * subtract "1" from the success counter (this is the main reason + * we keep these bitmaps!). + */ if (window->counter >= win_size) { - window->counter = win_size - 1; mask = 1; mask = (mask << (win_size - 1)); @@ -278,7 +308,11 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, } } + /* Increment frames-attempted counter */ window->counter = window->counter + 1; + + /* Shift bitmap by one frame (throw away oldest history), + * OR in "1", and increment "success" if this frame was successful. */ mask = window->data; window->data = (mask << 1); if (status != 0) { @@ -286,6 +320,7 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, window->data |= 0x1; } + /* Calculate current success ratio, avoid divide-by-0! */ if (window->counter > 0) window->success_ratio = 128 * (100 * window->success_counter) / window->counter; @@ -294,37 +329,40 @@ static int rs_collect_tx_data(struct iwl_rate_scale_data *windows, fail_count = window->counter - window->success_counter; + /* Calculate average throughput, if we have enough history. */ if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) window->average_tpt = (window->success_ratio * tpt + 64) / 128; else window->average_tpt = IWL_INVALID_VALUE; + /* Tag this window as having been updated */ window->stamp = jiffies; - return rc; + return 0; } -int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate, - struct iwl_scale_tbl_info *tbl, +/* + * Fill uCode API rate_n_flags field, based on "search" or "active" table. + */ +static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, + struct iwl4965_scale_tbl_info *tbl, int index, u8 use_green) { - int rc = 0; - if (is_legacy(tbl->lq_type)) { - mcs_rate->rate_n_flags = iwl_rates[index].plcp; + mcs_rate->rate_n_flags = iwl4965_rates[index].plcp; if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK; } else if (is_siso(tbl->lq_type)) { if (index > IWL_LAST_OFDM_RATE) index = IWL_LAST_OFDM_RATE; - mcs_rate->rate_n_flags = iwl_rates[index].plcp_siso | + mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso | RATE_MCS_HT_MSK; } else { if (index > IWL_LAST_OFDM_RATE) index = IWL_LAST_OFDM_RATE; - mcs_rate->rate_n_flags = iwl_rates[index].plcp_mimo | + mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo | RATE_MCS_HT_MSK; } @@ -343,7 +381,7 @@ int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate, } if (is_legacy(tbl->lq_type)) - return rc; + return; if (tbl->is_fat) { if (tbl->is_dup) @@ -359,27 +397,31 @@ int static rs_mcs_from_tbl(struct iwl_rate *mcs_rate, if (is_siso(tbl->lq_type)) mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK; } - return rc; } -static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate, - int phymode, struct iwl_scale_tbl_info *tbl, +/* + * Interpret uCode API's rate_n_flags format, + * fill "search" or "active" tx mode table. + */ +static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, + int phymode, struct iwl4965_scale_tbl_info *tbl, int *rate_idx) { int index; u32 ant_msk; - index = iwl_rate_index_from_plcp(mcs_rate->rate_n_flags); + index = iwl4965_rate_index_from_plcp(mcs_rate->rate_n_flags); if (index == IWL_RATE_INVALID) { *rate_idx = -1; - return -1; + return -EINVAL; } - tbl->is_SGI = 0; + tbl->is_SGI = 0; /* default legacy setup */ tbl->is_fat = 0; tbl->is_dup = 0; - tbl->antenna_type = ANT_BOTH; + tbl->antenna_type = ANT_BOTH; /* default MIMO setup */ + /* legacy rate format */ if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) { ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK); @@ -399,7 +441,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate, } *rate_idx = index; - } else if (iwl_rate_get_rate(mcs_rate->rate_n_flags) + /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */ + } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags) <= IWL_RATE_SISO_60M_PLCP) { tbl->lq_type = LQ_SISO; @@ -423,6 +466,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate, tbl->is_dup = 1; *rate_idx = index; + + /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */ } else { tbl->lq_type = LQ_MIMO; if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) @@ -439,8 +484,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl_rate *mcs_rate, return 0; } -static inline void rs_toggle_antenna(struct iwl_rate *new_rate, - struct iwl_scale_tbl_info *tbl) +static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, + struct iwl4965_scale_tbl_info *tbl) { if (tbl->antenna_type == ANT_AUX) { tbl->antenna_type = ANT_MAIN; @@ -453,18 +498,15 @@ static inline void rs_toggle_antenna(struct iwl_rate *new_rate, } } -static inline s8 rs_use_green(struct iwl_priv *priv) +static inline u8 rs_use_green(struct iwl4965_priv *priv, + struct ieee80211_conf *conf) { - s8 rc = 0; -#ifdef CONFIG_IWLWIFI_HT - if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht) - return 0; - - if ((priv->current_assoc_ht.is_green_field) && - !(priv->current_assoc_ht.operating_mode & 0x4)) - rc = 1; -#endif /*CONFIG_IWLWIFI_HT */ - return rc; +#ifdef CONFIG_IWL4965_HT + return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && + priv->current_ht_config.is_green_field && + !priv->current_ht_config.non_GF_STA_present); +#endif /* CONFIG_IWL4965_HT */ + return 0; } /** @@ -474,9 +516,9 @@ static inline s8 rs_use_green(struct iwl_priv *priv) * basic available rates. * */ -static void rs_get_supported_rates(struct iwl_rate_scale_priv *lq_data, +static void rs_get_supported_rates(struct iwl4965_rate_scale_priv *lq_data, struct ieee80211_hdr *hdr, - enum iwl_table_type rate_type, + enum iwl4965_table_type rate_type, u16 *data_rate) { if (is_legacy(rate_type)) @@ -498,7 +540,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) u8 high = IWL_RATE_INVALID; u8 low = IWL_RATE_INVALID; - /* 802.11A or ht walks to the next literal adjascent rate in + /* 802.11A or ht walks to the next literal adjacent rate in * the rate table */ if (is_a_band(rate_type) || !is_legacy(rate_type)) { int i; @@ -527,7 +569,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) low = index; while (low != IWL_RATE_INVALID) { - low = iwl_rates[low].prev_rs; + low = iwl4965_rates[low].prev_rs; if (low == IWL_RATE_INVALID) break; if (rate_mask & (1 << low)) @@ -537,7 +579,7 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) high = index; while (high != IWL_RATE_INVALID) { - high = iwl_rates[high].next_rs; + high = iwl4965_rates[high].next_rs; if (high == IWL_RATE_INVALID) break; if (rate_mask & (1 << high)) @@ -548,9 +590,9 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type) return (high << 8) | low; } -static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data, - struct iwl_scale_tbl_info *tbl, u8 scale_index, - u8 ht_possible, struct iwl_rate *mcs_rate) +static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data, + struct iwl4965_scale_tbl_info *tbl, u8 scale_index, + u8 ht_possible, struct iwl4965_rate *mcs_rate) { s32 low; u16 rate_mask; @@ -579,8 +621,9 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data, rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask); - /* mask with station rate restriction */ + /* Mask with station rate restriction */ if (is_legacy(tbl->lq_type)) { + /* supp_rates has no CCK bits in A mode */ if (lq_data->phymode == (u8) MODE_IEEE80211A) rate_mask = (u16)(rate_mask & (lq_data->supp_rates << IWL_FIRST_OFDM_RATE)); @@ -588,11 +631,10 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data, rate_mask = (u16)(rate_mask & lq_data->supp_rates); } - /* if we did switched from HT to legacy check current rate */ - if ((switch_to_legacy) && - (rate_mask & (1 << scale_index))) { + /* If we switched from HT to legacy, check current rate */ + if (switch_to_legacy && (rate_mask & (1 << scale_index))) { rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); - return 0; + return; } high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type); @@ -602,10 +644,11 @@ static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data, rs_mcs_from_tbl(mcs_rate, tbl, low, is_green); else rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); - - return 0; } +/* + * mac80211 sends us Tx status + */ static void rs_tx_status(void *priv_rate, struct net_device *dev, struct sk_buff *skb, @@ -614,17 +657,17 @@ static void rs_tx_status(void *priv_rate, int status; u8 retries; int rs_index, index = 0; - struct iwl_rate_scale_priv *lq; - struct iwl_link_quality_cmd *table; + struct iwl4965_rate_scale_priv *lq; + struct iwl4965_link_quality_cmd *table; struct sta_info *sta; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct iwl_rate_scale_data *window = NULL; - struct iwl_rate_scale_data *search_win = NULL; - struct iwl_rate tx_mcs; - struct iwl_scale_tbl_info tbl_type; - struct iwl_scale_tbl_info *curr_tbl, *search_tbl; + struct iwl4965_rate_scale_data *window = NULL; + struct iwl4965_rate_scale_data *search_win = NULL; + struct iwl4965_rate tx_mcs; + struct iwl4965_scale_tbl_info tbl_type; + struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; u8 active_index = 0; u16 fc = le16_to_cpu(hdr->frame_control); s32 tpt = 0; @@ -648,7 +691,7 @@ static void rs_tx_status(void *priv_rate, return; } - lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv; + lq = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; if (!priv->lq_mngr.lq_ready) return; @@ -659,16 +702,19 @@ static void rs_tx_status(void *priv_rate, table = &lq->lq; active_index = lq->active_tbl; + /* Get mac80211 antenna info */ lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx); if (!lq->antenna) lq->antenna = lq->valid_antenna; + /* Ignore mac80211 antenna info for now */ lq->antenna = lq->valid_antenna; + curr_tbl = &(lq->lq_info[active_index]); search_tbl = &(lq->lq_info[(1 - active_index)]); - window = (struct iwl_rate_scale_data *) + window = (struct iwl4965_rate_scale_data *) &(curr_tbl->win[0]); - search_win = (struct iwl_rate_scale_data *) + search_win = (struct iwl4965_rate_scale_data *) &(search_tbl->win[0]); tx_mcs.rate_n_flags = tx_resp->control.tx_rate; @@ -682,6 +728,14 @@ static void rs_tx_status(void *priv_rate, return; } + /* + * Ignore this Tx frame response if its initial rate doesn't match + * that of latest Link Quality command. There may be stragglers + * from a previous Link Quality command, but we're no longer interested + * in those; they're either from the "active" mode while we're trying + * to check "search" mode, or a prior "search" mode after we've moved + * to a new "search" mode (which might become the new "active" mode). + */ if (retries && (tx_mcs.rate_n_flags != le32_to_cpu(table->rs_table[0].rate_n_flags))) { @@ -692,12 +746,17 @@ static void rs_tx_status(void *priv_rate, return; } + /* Update frame history window with "failure" for each Tx retry. */ while (retries) { + /* Look up the rate and other info used for each tx attempt. + * Each tx attempt steps one entry deeper in the rate table. */ tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, &tbl_type, &rs_index); + /* If type matches "search" table, + * add failure to "search" history */ if ((tbl_type.lq_type == search_tbl->lq_type) && (tbl_type.antenna_type == search_tbl->antenna_type) && (tbl_type.is_SGI == search_tbl->is_SGI)) { @@ -705,8 +764,10 @@ static void rs_tx_status(void *priv_rate, tpt = search_tbl->expected_tpt[rs_index]; else tpt = 0; - rs_collect_tx_data(search_win, - rs_index, tpt, 0); + rs_collect_tx_data(search_win, rs_index, tpt, 0); + + /* Else if type matches "current/active" table, + * add failure to "current/active" history */ } else if ((tbl_type.lq_type == curr_tbl->lq_type) && (tbl_type.antenna_type == curr_tbl->antenna_type) && (tbl_type.is_SGI == curr_tbl->is_SGI)) { @@ -716,6 +777,9 @@ static void rs_tx_status(void *priv_rate, tpt = 0; rs_collect_tx_data(window, rs_index, tpt, 0); } + + /* If not searching for a new mode, increment failed counter + * ... this helps determine when to start searching again */ if (lq->stay_in_tbl) lq->total_failed++; --retries; @@ -723,6 +787,11 @@ static void rs_tx_status(void *priv_rate, } + /* + * Find (by rate) the history window to update with final Tx attempt; + * if Tx was successful first try, use original rate, + * else look up the rate that was, finally, successful. + */ if (!tx_resp->retry_count) tx_mcs.rate_n_flags = tx_resp->control.tx_rate; else @@ -732,11 +801,14 @@ static void rs_tx_status(void *priv_rate, rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, &tbl_type, &rs_index); + /* Update frame history window with "success" if Tx got ACKed ... */ if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) status = 1; else status = 0; + /* If type matches "search" table, + * add final tx status to "search" history */ if ((tbl_type.lq_type == search_tbl->lq_type) && (tbl_type.antenna_type == search_tbl->antenna_type) && (tbl_type.is_SGI == search_tbl->is_SGI)) { @@ -746,6 +818,9 @@ static void rs_tx_status(void *priv_rate, tpt = 0; rs_collect_tx_data(search_win, rs_index, tpt, status); + + /* Else if type matches "current/active" table, + * add final tx status to "current/active" history */ } else if ((tbl_type.lq_type == curr_tbl->lq_type) && (tbl_type.antenna_type == curr_tbl->antenna_type) && (tbl_type.is_SGI == curr_tbl->is_SGI)) { @@ -756,6 +831,8 @@ static void rs_tx_status(void *priv_rate, rs_collect_tx_data(window, rs_index, tpt, status); } + /* If not searching for new mode, increment success/failed counter + * ... these help determine when to start searching again */ if (lq->stay_in_tbl) { if (status) lq->total_success++; @@ -763,48 +840,53 @@ static void rs_tx_status(void *priv_rate, lq->total_failed++; } + /* See if there's a better rate or modulation mode to try. */ rs_rate_scale_perform(priv, dev, hdr, sta); sta_info_put(sta); return; } static u8 rs_is_ant_connected(u8 valid_antenna, - enum iwl_antenna_type antenna_type) + enum iwl4965_antenna_type antenna_type) { if (antenna_type == ANT_AUX) return ((valid_antenna & 0x2) ? 1:0); else if (antenna_type == ANT_MAIN) return ((valid_antenna & 0x1) ? 1:0); - else if (antenna_type == ANT_BOTH) { - if ((valid_antenna & 0x3) == 0x3) - return 1; - else - return 0; - } + else if (antenna_type == ANT_BOTH) + return ((valid_antenna & 0x3) == 0x3); return 1; } static u8 rs_is_other_ant_connected(u8 valid_antenna, - enum iwl_antenna_type antenna_type) + enum iwl4965_antenna_type antenna_type) { if (antenna_type == ANT_AUX) - return (rs_is_ant_connected(valid_antenna, ANT_MAIN)); + return rs_is_ant_connected(valid_antenna, ANT_MAIN); else - return (rs_is_ant_connected(valid_antenna, ANT_AUX)); + return rs_is_ant_connected(valid_antenna, ANT_AUX); return 0; } +/* + * Begin a period of staying with a selected modulation mode. + * Set "stay_in_tbl" flag to prevent any mode switches. + * Set frame tx success limits according to legacy vs. high-throughput, + * and reset overall (spanning all rates) tx success history statistics. + * These control how long we stay using same modulation mode before + * searching for a new mode. + */ static void rs_set_stay_in_table(u8 is_legacy, - struct iwl_rate_scale_priv *lq_data) + struct iwl4965_rate_scale_priv *lq_data) { IWL_DEBUG_HT("we are staying in the same table\n"); - lq_data->stay_in_tbl = 1; + lq_data->stay_in_tbl = 1; /* only place this gets set */ if (is_legacy) { lq_data->table_count_limit = IWL_LEGACY_TABLE_COUNT; lq_data->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; - lq_data->max_success_limit = IWL_LEGACY_TABLE_COUNT; + lq_data->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT; } else { lq_data->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT; lq_data->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT; @@ -815,8 +897,11 @@ static void rs_set_stay_in_table(u8 is_legacy, lq_data->total_success = 0; } -static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data, - struct iwl_scale_tbl_info *tbl) +/* + * Find correct throughput table for given mode of modulation + */ +static void rs_get_expected_tpt_table(struct iwl4965_rate_scale_priv *lq_data, + struct iwl4965_scale_tbl_info *tbl) { if (is_legacy(tbl->lq_type)) { if (!is_a_band(tbl->lq_type)) @@ -848,18 +933,34 @@ static void rs_get_expected_tpt_table(struct iwl_rate_scale_priv *lq_data, tbl->expected_tpt = expected_tpt_G; } -#ifdef CONFIG_IWLWIFI_HT -static s32 rs_get_best_rate(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, - struct iwl_scale_tbl_info *tbl, +#ifdef CONFIG_IWL4965_HT +/* + * Find starting rate for new "search" high-throughput mode of modulation. + * Goal is to find lowest expected rate (under perfect conditions) that is + * above the current measured throughput of "active" mode, to give new mode + * a fair chance to prove itself without too many challenges. + * + * This gets called when transitioning to more aggressive modulation + * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive + * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need + * to decrease to match "active" throughput. When moving from MIMO to SISO, + * bit rate will typically need to increase, but not if performance was bad. + */ +static s32 rs_get_best_rate(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct iwl4965_scale_tbl_info *tbl, /* "search" */ u16 rate_mask, s8 index, s8 rate) { - struct iwl_scale_tbl_info *active_tbl = + /* "active" values */ + struct iwl4965_scale_tbl_info *active_tbl = &(lq_data->lq_info[lq_data->active_tbl]); - s32 new_rate, high, low, start_hi; s32 active_sr = active_tbl->win[index].success_ratio; - s32 *tpt_tbl = tbl->expected_tpt; s32 active_tpt = active_tbl->expected_tpt[index]; + + /* expected "search" throughput */ + s32 *tpt_tbl = tbl->expected_tpt; + + s32 new_rate, high, low, start_hi; u16 high_low; new_rate = high = low = start_hi = IWL_RATE_INVALID; @@ -870,6 +971,21 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, low = high_low & 0xff; high = (high_low >> 8) & 0xff; + /* + * Lower the "search" bit rate, to give new "search" mode + * approximately the same throughput as "active" if: + * + * 1) "Active" mode has been working modestly well (but not + * great), and expected "search" throughput (under perfect + * conditions) at candidate rate is above the actual + * measured "active" throughput (but less than expected + * "active" throughput under perfect conditions). + * OR + * 2) "Active" mode has been working perfectly or very well + * and expected "search" throughput (under perfect + * conditions) at candidate rate is above expected + * "active" throughput (under perfect conditions). + */ if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) && ((active_sr > IWL_RATE_DECREASE_TH) && (active_sr <= IWL_RATE_HIGH_TH) && @@ -877,21 +993,38 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, ((active_sr >= IWL_RATE_SCALE_SWITCH) && (tpt_tbl[rate] > active_tpt))) { + /* (2nd or later pass) + * If we've already tried to raise the rate, and are + * now trying to lower it, use the higher rate. */ if (start_hi != IWL_RATE_INVALID) { new_rate = start_hi; break; } + new_rate = rate; + + /* Loop again with lower rate */ if (low != IWL_RATE_INVALID) rate = low; + + /* Lower rate not available, use the original */ else break; + + /* Else try to raise the "search" rate to match "active" */ } else { + /* (2nd or later pass) + * If we've already tried to lower the rate, and are + * now trying to raise it, use the lower rate. */ if (new_rate != IWL_RATE_INVALID) break; + + /* Loop again with higher rate */ else if (high != IWL_RATE_INVALID) { start_hi = high; rate = high; + + /* Higher rate not available, use the original */ } else { new_rate = rate; break; @@ -901,24 +1034,29 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, return new_rate; } -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT */ static inline u8 rs_is_both_ant_supp(u8 valid_antenna) { return (rs_is_ant_connected(valid_antenna, ANT_BOTH)); } -static int rs_switch_to_mimo(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, - struct iwl_scale_tbl_info *tbl, int index) +/* + * Set up search table for MIMO + */ +static int rs_switch_to_mimo(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct ieee80211_conf *conf, + struct sta_info *sta, + struct iwl4965_scale_tbl_info *tbl, int index) { - int rc = -1; -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT u16 rate_mask; s32 rate; s8 is_green = lq_data->is_green; - if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht) + if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || + !sta->ht_info.ht_supported) return -1; IWL_DEBUG_HT("LQ: try to switch to MIMO\n"); @@ -926,26 +1064,27 @@ static int rs_switch_to_mimo(struct iwl_priv *priv, rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask); - if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) + if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) return -1; + /* Need both Tx chains/antennas to support MIMO */ if (!rs_is_both_ant_supp(lq_data->antenna)) return -1; - rc = 0; tbl->is_dup = lq_data->is_dup; tbl->action = 0; - if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ) + if (priv->current_ht_config.supported_chan_width + == IWL_CHANNEL_WIDTH_40MHZ) tbl->is_fat = 1; else tbl->is_fat = 0; if (tbl->is_fat) { - if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY) + if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) tbl->is_SGI = 1; else tbl->is_SGI = 0; - } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY) + } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY) tbl->is_SGI = 1; else tbl->is_SGI = 0; @@ -961,43 +1100,49 @@ static int rs_switch_to_mimo(struct iwl_priv *priv, IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", tbl->current_rate.rate_n_flags, is_green); - -#endif /*CONFIG_IWLWIFI_HT */ - return rc; + return 0; +#else + return -1; +#endif /*CONFIG_IWL4965_HT */ } -static int rs_switch_to_siso(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, - struct iwl_scale_tbl_info *tbl, int index) +/* + * Set up search table for SISO + */ +static int rs_switch_to_siso(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct ieee80211_conf *conf, + struct sta_info *sta, + struct iwl4965_scale_tbl_info *tbl, int index) { - int rc = -1; -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT u16 rate_mask; u8 is_green = lq_data->is_green; s32 rate; IWL_DEBUG_HT("LQ: try to switch to SISO\n"); - if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht) + if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || + !sta->ht_info.ht_supported) return -1; - rc = 0; tbl->is_dup = lq_data->is_dup; tbl->lq_type = LQ_SISO; tbl->action = 0; rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask); - if (priv->current_channel_width == IWL_CHANNEL_WIDTH_40MHZ) + if (priv->current_ht_config.supported_chan_width + == IWL_CHANNEL_WIDTH_40MHZ) tbl->is_fat = 1; else tbl->is_fat = 0; if (tbl->is_fat) { - if (priv->current_assoc_ht.sgf & HT_SHORT_GI_40MHZ_ONLY) + if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) tbl->is_SGI = 1; else tbl->is_SGI = 0; - } else if (priv->current_assoc_ht.sgf & HT_SHORT_GI_20MHZ_ONLY) + } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY) tbl->is_SGI = 1; else tbl->is_SGI = 0; @@ -1017,23 +1162,30 @@ static int rs_switch_to_siso(struct iwl_priv *priv, rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green); IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", tbl->current_rate.rate_n_flags, is_green); + return 0; +#else + return -1; -#endif /*CONFIG_IWLWIFI_HT */ - return rc; +#endif /*CONFIG_IWL4965_HT */ } -static int rs_move_legacy_other(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, +/* + * Try to switch to new modulation mode from legacy + */ +static int rs_move_legacy_other(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct ieee80211_conf *conf, + struct sta_info *sta, int index) { - int rc = 0; - struct iwl_scale_tbl_info *tbl = + int ret = 0; + struct iwl4965_scale_tbl_info *tbl = &(lq_data->lq_info[lq_data->active_tbl]); - struct iwl_scale_tbl_info *search_tbl = + struct iwl4965_scale_tbl_info *search_tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]); - 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)); + struct iwl4965_rate_scale_data *window = &(tbl->win[index]); + u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - + (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action = tbl->action; for (; ;) { @@ -1043,12 +1195,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv, search_tbl->lq_type = LQ_NONE; lq_data->action_counter++; + + /* Don't change antenna if success has been great */ if (window->success_ratio >= IWL_RS_GOOD_RATIO) break; + + /* Don't change antenna if other one is not connected */ if (!rs_is_other_ant_connected(lq_data->antenna, tbl->antenna_type)) break; + /* Set up search table to try other antenna */ memcpy(search_tbl, tbl, sz); rs_toggle_antenna(&(search_tbl->current_rate), @@ -1059,35 +1216,37 @@ static int rs_move_legacy_other(struct iwl_priv *priv, case IWL_LEGACY_SWITCH_SISO: IWL_DEBUG_HT("LQ: Legacy switch to SISO\n"); + + /* Set up search table to try SISO */ memcpy(search_tbl, tbl, sz); search_tbl->lq_type = LQ_SISO; search_tbl->is_SGI = 0; search_tbl->is_fat = 0; - rc = rs_switch_to_siso(priv, lq_data, search_tbl, - index); - if (!rc) { + ret = rs_switch_to_siso(priv, lq_data, conf, sta, + search_tbl, index); + if (!ret) { lq_data->search_better_tbl = 1; lq_data->action_counter = 0; - } - if (!rc) goto out; + } break; case IWL_LEGACY_SWITCH_MIMO: IWL_DEBUG_HT("LQ: Legacy switch MIMO\n"); + + /* Set up search table to try MIMO */ memcpy(search_tbl, tbl, sz); search_tbl->lq_type = LQ_MIMO; search_tbl->is_SGI = 0; search_tbl->is_fat = 0; search_tbl->antenna_type = ANT_BOTH; - rc = rs_switch_to_mimo(priv, lq_data, search_tbl, - index); - if (!rc) { + ret = rs_switch_to_mimo(priv, lq_data, conf, sta, + search_tbl, index); + if (!ret) { lq_data->search_better_tbl = 1; lq_data->action_counter = 0; - } - if (!rc) goto out; + } break; } tbl->action++; @@ -1108,19 +1267,24 @@ static int rs_move_legacy_other(struct iwl_priv *priv, } -static int rs_move_siso_to_other(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, +/* + * Try to switch to new modulation mode from SISO + */ +static int rs_move_siso_to_other(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct ieee80211_conf *conf, + struct sta_info *sta, int index) { - int rc = -1; + int ret; u8 is_green = lq_data->is_green; - struct iwl_scale_tbl_info *tbl = + struct iwl4965_scale_tbl_info *tbl = &(lq_data->lq_info[lq_data->active_tbl]); - struct iwl_scale_tbl_info *search_tbl = + struct iwl4965_scale_tbl_info *search_tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]); - 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)); + struct iwl4965_rate_scale_data *window = &(tbl->win[index]); + u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - + (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action = tbl->action; for (;;) { @@ -1150,13 +1314,12 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, search_tbl->is_SGI = 0; search_tbl->is_fat = 0; search_tbl->antenna_type = ANT_BOTH; - rc = rs_switch_to_mimo(priv, lq_data, search_tbl, - index); - if (!rc) + ret = rs_switch_to_mimo(priv, lq_data, conf, sta, + search_tbl, index); + if (!ret) { lq_data->search_better_tbl = 1; - - if (!rc) goto out; + } break; case IWL_SISO_SWITCH_GI: IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); @@ -1199,18 +1362,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, return 0; } -static int rs_move_mimo_to_other(struct iwl_priv *priv, - struct iwl_rate_scale_priv *lq_data, +/* + * Try to switch to new modulation mode from MIMO + */ +static int rs_move_mimo_to_other(struct iwl4965_priv *priv, + struct iwl4965_rate_scale_priv *lq_data, + struct ieee80211_conf *conf, + struct sta_info *sta, int index) { - int rc = -1; + int ret; s8 is_green = lq_data->is_green; - struct iwl_scale_tbl_info *tbl = + struct iwl4965_scale_tbl_info *tbl = &(lq_data->lq_info[lq_data->active_tbl]); - struct iwl_scale_tbl_info *search_tbl = + struct iwl4965_scale_tbl_info *search_tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]); - u32 sz = (sizeof(struct iwl_scale_tbl_info) - - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); + u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - + (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action = tbl->action; for (;;) { @@ -1219,6 +1387,8 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, case IWL_MIMO_SWITCH_ANTENNA_A: case IWL_MIMO_SWITCH_ANTENNA_B: IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); + + /* Set up new search table for SISO */ memcpy(search_tbl, tbl, sz); search_tbl->lq_type = LQ_SISO; search_tbl->is_SGI = 0; @@ -1228,9 +1398,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, else search_tbl->antenna_type = ANT_AUX; - rc = rs_switch_to_siso(priv, lq_data, search_tbl, - index); - if (!rc) { + ret = rs_switch_to_siso(priv, lq_data, conf, sta, + search_tbl, index); + if (!ret) { lq_data->search_better_tbl = 1; goto out; } @@ -1238,6 +1408,8 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, case IWL_MIMO_SWITCH_GI: IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n"); + + /* Set up new search table for MIMO */ memcpy(search_tbl, tbl, sz); search_tbl->lq_type = LQ_MIMO; search_tbl->antenna_type = ANT_BOTH; @@ -1247,6 +1419,13 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, else search_tbl->is_SGI = 1; lq_data->search_better_tbl = 1; + + /* + * If active table already uses the fastest possible + * modulation (dual stream with short guard interval), + * and it's working well, there's no need to look + * for a better type of modulation! + */ if ((tbl->lq_type == LQ_MIMO) && (tbl->is_SGI)) { s32 tpt = lq_data->last_tpt / 100; @@ -1279,9 +1458,16 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, } -static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data) +/* + * Check whether we should continue using same modulation mode, or + * begin search for a new mode, based on: + * 1) # tx successes or failures while using this mode + * 2) # times calling this function + * 3) elapsed time in this mode (not used, for now) + */ +static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) { - struct iwl_scale_tbl_info *tbl; + struct iwl4965_scale_tbl_info *tbl; int i; int active_tbl; int flush_interval_passed = 0; @@ -1290,15 +1476,27 @@ static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data) tbl = &(lq_data->lq_info[active_tbl]); + /* If we've been disallowing search, see if we should now allow it */ if (lq_data->stay_in_tbl) { + /* Elapsed time using current modulation mode */ if (lq_data->flush_timer) flush_interval_passed = time_after(jiffies, (unsigned long)(lq_data->flush_timer + IWL_RATE_SCALE_FLUSH_INTVL)); + /* For now, disable the elapsed time criterion */ flush_interval_passed = 0; + + /* + * Check if we should allow search for new modulation mode. + * If many frames have failed or succeeded, or we've used + * this same modulation for a long time, allow search, and + * reset history stats that keep track of whether we should + * allow a new search. Also (below) reset all bitmaps and + * stats in active history. + */ if ((lq_data->total_failed > lq_data->max_failure_limit) || (lq_data->total_success > lq_data->max_success_limit) || ((!lq_data->search_better_tbl) && (lq_data->flush_timer) @@ -1307,11 +1505,20 @@ static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data) lq_data->total_failed, lq_data->total_success, flush_interval_passed); - lq_data->stay_in_tbl = 0; + + /* Allow search for new mode */ + lq_data->stay_in_tbl = 0; /* only place reset */ lq_data->total_failed = 0; lq_data->total_success = 0; lq_data->flush_timer = 0; - } else if (lq_data->table_count > 0) { + + /* + * Else if we've used this modulation mode enough repetitions + * (regardless of elapsed time or success/failure), reset + * history bitmaps and rate-specific stats for all rates in + * active table. + */ + } else { lq_data->table_count++; if (lq_data->table_count >= lq_data->table_count_limit) { @@ -1324,6 +1531,9 @@ static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data) } } + /* If transitioning to allow "search", reset all history + * bitmaps and stats in active table (this will become the new + * "search" table). */ if (!lq_data->stay_in_tbl) { for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&(tbl->win[i])); @@ -1331,16 +1541,22 @@ static void rs_stay_in_table(struct iwl_rate_scale_priv *lq_data) } } -static void rs_rate_scale_perform(struct iwl_priv *priv, +/* + * Do rate scaling and search for new modulation mode. + */ +static void rs_rate_scale_perform(struct iwl4965_priv *priv, struct net_device *dev, struct ieee80211_hdr *hdr, struct sta_info *sta) { + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_hw *hw = local_to_hw(local); + struct ieee80211_conf *conf = &hw->conf; int low = IWL_RATE_INVALID; int high = IWL_RATE_INVALID; int index; int i; - struct iwl_rate_scale_data *window = NULL; + struct iwl4965_rate_scale_data *window = NULL; int current_tpt = IWL_INVALID_VALUE; int low_tpt = IWL_INVALID_VALUE; int high_tpt = IWL_INVALID_VALUE; @@ -1348,10 +1564,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, s8 scale_action = 0; u16 fc, rate_mask; u8 update_lq = 0; - struct iwl_rate_scale_priv *lq_data; - struct iwl_scale_tbl_info *tbl, *tbl1; + struct iwl4965_rate_scale_priv *lq_data; + struct iwl4965_scale_tbl_info *tbl, *tbl1; u16 rate_scale_index_msk = 0; - struct iwl_rate mcs_rate; + struct iwl4965_rate mcs_rate; u8 is_green = 0; u8 active_tbl = 0; u8 done_search = 0; @@ -1374,8 +1590,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, IWL_DEBUG_RATE("still rate scaling not ready\n"); return; } - lq_data = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv; + lq_data = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; + /* + * Select rate-scale / modulation-mode table to work with in + * the rest of this function: "search" if searching for better + * modulation mode, or "active" if doing rate scaling within a mode. + */ if (!lq_data->search_better_tbl) active_tbl = lq_data->active_tbl; else @@ -1384,11 +1605,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, tbl = &(lq_data->lq_info[active_tbl]); is_green = lq_data->is_green; + /* current tx rate */ index = sta->last_txrate; IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, tbl->lq_type); + /* rates available for this association, and for modulation mode */ rs_get_supported_rates(lq_data, hdr, tbl->lq_type, &rate_mask); @@ -1397,6 +1620,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* mask with station rate restriction */ if (is_legacy(tbl->lq_type)) { if (lq_data->phymode == (u8) MODE_IEEE80211A) + /* supp_rates has no CCK bits in A mode */ rate_scale_index_msk = (u16) (rate_mask & (lq_data->supp_rates << IWL_FIRST_OFDM_RATE)); else @@ -1409,11 +1633,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (!rate_scale_index_msk) rate_scale_index_msk = rate_mask; + /* If current rate is no longer supported on current association, + * or user changed preferences for rates, find a new supported rate. */ if (index < 0 || !((1 << index) & rate_scale_index_msk)) { index = IWL_INVALID_VALUE; update_lq = 1; - /* get the lowest availabe rate */ + /* get the highest available rate */ for (i = 0; i <= IWL_RATE_COUNT; i++) { if ((1 << i) & rate_scale_index_msk) index = i; @@ -1425,11 +1651,19 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } } + /* Get expected throughput table and history window for current rate */ if (!tbl->expected_tpt) rs_get_expected_tpt_table(lq_data, tbl); window = &(tbl->win[index]); + /* + * If there is not enough history to calculate actual average + * throughput, keep analyzing results of more tx frames, without + * changing rate or mode (bypass most of the rest of this function). + * Set up new rate table in uCode only if old rate is not supported + * in current association (use new rate found above). + */ fail_count = window->counter - window->success_counter; if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) @@ -1437,8 +1671,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, IWL_DEBUG_RATE("LQ: still below TH succ %d total %d " "for index %d\n", window->success_counter, window->counter, index); + + /* Can't calculate this yet; not enough history */ window->average_tpt = IWL_INVALID_VALUE; + + /* Should we stay with this modulation mode, + * or search for a new one? */ rs_stay_in_table(lq_data); + + /* Set up new rate table in uCode, if needed */ if (update_lq) { rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq); @@ -1446,13 +1687,19 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } goto out; + /* Else we have enough samples; calculate estimate of + * actual average throughput */ } else window->average_tpt = ((window->success_ratio * tbl->expected_tpt[index] + 64) / 128); + /* If we are searching for better modulation mode, check success. */ if (lq_data->search_better_tbl) { int success_limit = IWL_RATE_SCALE_SWITCH; + /* If good success, continue using the "search" mode; + * no need to send new link quality command, since we're + * continuing to use the setup that we've been trying. */ if ((window->success_ratio > success_limit) || (window->average_tpt > lq_data->last_tpt)) { if (!is_legacy(tbl->lq_type)) { @@ -1464,55 +1711,78 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, lq_data->last_tpt); lq_data->enable_counter = 1; } + /* Swap tables; "search" becomes "active" */ lq_data->active_tbl = active_tbl; current_tpt = window->average_tpt; + + /* Else poor success; go back to mode in "active" table */ } else { + /* Nullify "search" table */ tbl->lq_type = LQ_NONE; + + /* Revert to "active" table */ active_tbl = lq_data->active_tbl; tbl = &(lq_data->lq_info[active_tbl]); - index = iwl_rate_index_from_plcp( + /* Revert to "active" rate and throughput info */ + index = iwl4965_rate_index_from_plcp( tbl->current_rate.rate_n_flags); + current_tpt = lq_data->last_tpt; + /* Need to set up a new rate table in uCode */ update_lq = 1; - current_tpt = lq_data->last_tpt; IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n"); } + + /* Either way, we've made a decision; modulation mode + * search is done, allow rate adjustment next time. */ lq_data->search_better_tbl = 0; - done_search = 1; + done_search = 1; /* Don't switch modes below! */ goto lq_update; } + /* (Else) not in search of better modulation mode, try for better + * starting rate, while staying in this mode. */ high_low = rs_get_adjacent_rate(index, rate_scale_index_msk, tbl->lq_type); low = high_low & 0xff; high = (high_low >> 8) & 0xff; + /* Collect measured throughputs for current and adjacent rates */ current_tpt = window->average_tpt; - if (low != IWL_RATE_INVALID) low_tpt = tbl->win[low].average_tpt; - if (high != IWL_RATE_INVALID) high_tpt = tbl->win[high].average_tpt; - + /* Assume rate increase */ scale_action = 1; + /* Too many failures, decrease rate */ if ((window->success_ratio <= IWL_RATE_DECREASE_TH) || (current_tpt == 0)) { IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); scale_action = -1; + + /* No throughput measured yet for adjacent rates; try increase. */ } else if ((low_tpt == IWL_INVALID_VALUE) && (high_tpt == IWL_INVALID_VALUE)) scale_action = 1; + + /* Both adjacent throughputs are measured, but neither one has better + * throughput; we're using the best rate, don't change it! */ else if ((low_tpt != IWL_INVALID_VALUE) && (high_tpt != IWL_INVALID_VALUE) && (low_tpt < current_tpt) && (high_tpt < current_tpt)) scale_action = 0; + + /* At least one adjacent rate's throughput is measured, + * and may have better performance. */ else { + /* Higher adjacent rate's throughput is measured */ if (high_tpt != IWL_INVALID_VALUE) { + /* Higher rate has better throughput */ if (high_tpt > current_tpt) scale_action = 1; else { @@ -1520,7 +1790,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ("decrease rate because of high tpt\n"); scale_action = -1; } + + /* Lower adjacent rate's throughput is measured */ } else if (low_tpt != IWL_INVALID_VALUE) { + /* Lower rate has better throughput */ if (low_tpt > current_tpt) { IWL_DEBUG_RATE ("decrease rate because of low tpt\n"); @@ -1530,23 +1803,30 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } } + /* Sanity check; asked for decrease, but success rate or throughput + * has been good at old rate. Don't change it. */ if (scale_action == -1) { if ((low != IWL_RATE_INVALID) && ((window->success_ratio > IWL_RATE_HIGH_TH) || (current_tpt > (100 * tbl->expected_tpt[low])))) scale_action = 0; + + /* Sanity check; asked for increase, but success rate has not been great + * even at old rate, higher rate will be worse. Don't change it. */ } else if ((scale_action == 1) && (window->success_ratio < IWL_RATE_INCREASE_TH)) scale_action = 0; switch (scale_action) { case -1: + /* Decrease starting rate, update uCode's rate table */ if (low != IWL_RATE_INVALID) { update_lq = 1; index = low; } break; case 1: + /* Increase starting rate, update uCode's rate table */ if (high != IWL_RATE_INVALID) { update_lq = 1; index = high; @@ -1554,6 +1834,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, break; case 0: + /* No change */ default: break; } @@ -1563,29 +1844,44 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, index, scale_action, low, high, tbl->lq_type); lq_update: + /* Replace uCode's rate table for the destination station. */ if (update_lq) { rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq); rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC); } + + /* Should we stay with this modulation mode, or search for a new one? */ rs_stay_in_table(lq_data); + /* + * Search for new modulation mode if we're: + * 1) Not changing rates right now + * 2) Not just finishing up a search + * 3) Allowing a new search + */ if (!update_lq && !done_search && !lq_data->stay_in_tbl) { + /* Save current throughput to compare with "search" throughput*/ lq_data->last_tpt = current_tpt; + /* Select a new "search" modulation mode to try. + * If one is found, set up the new "search" table. */ if (is_legacy(tbl->lq_type)) - rs_move_legacy_other(priv, lq_data, index); + rs_move_legacy_other(priv, lq_data, conf, sta, index); else if (is_siso(tbl->lq_type)) - rs_move_siso_to_other(priv, lq_data, index); + rs_move_siso_to_other(priv, lq_data, conf, sta, index); else - rs_move_mimo_to_other(priv, lq_data, index); + rs_move_mimo_to_other(priv, lq_data, conf, sta, index); + /* If new "search" mode was selected, set up in uCode table */ if (lq_data->search_better_tbl) { + /* Access the "search" table, clear its history. */ tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]); for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&(tbl->win[i])); - index = iwl_rate_index_from_plcp( + /* Use new "search" start rate */ + index = iwl4965_rate_index_from_plcp( tbl->current_rate.rate_n_flags); IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", @@ -1594,11 +1890,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, &lq_data->lq); rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC); } - tbl1 = &(lq_data->lq_info[lq_data->active_tbl]); + /* If the "active" (non-search) mode was legacy, + * and we've tried switching antennas, + * but we haven't been able to try HT modes (not available), + * stay with best antenna legacy modulation for a while + * before next round of mode comparisons. */ + tbl1 = &(lq_data->lq_info[lq_data->active_tbl]); if (is_legacy(tbl1->lq_type) && -#ifdef CONFIG_IWLWIFI_HT - !priv->current_assoc_ht.is_ht && +#ifdef CONFIG_IWL4965_HT + (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && #endif (lq_data->action_counter >= 1)) { lq_data->action_counter = 0; @@ -1606,19 +1907,31 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, rs_set_stay_in_table(1, lq_data); } + /* If we're in an HT mode, and all 3 mode switch actions + * have been tried and compared, stay in this best modulation + * mode for a while before next round of mode comparisons. */ if (lq_data->enable_counter && (lq_data->action_counter >= IWL_ACTION_LIMIT)) { -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT_AGG + /* If appropriate, set up aggregation! */ if ((lq_data->last_tpt > TID_AGG_TPT_THREHOLD) && (priv->lq_mngr.agg_ctrl.auto_agg)) { priv->lq_mngr.agg_ctrl.tid_retry = TID_ALL_SPECIFIED; schedule_work(&priv->agg_work); } -#endif /*CONFIG_IWLWIFI_HT_AGG */ +#endif /*CONFIG_IWL4965_HT_AGG */ lq_data->action_counter = 0; rs_set_stay_in_table(0, lq_data); } + + /* + * Else, don't search for a new modulation mode. + * Put new timestamp in stay-in-modulation-mode flush timer if: + * 1) Not changing rates right now + * 2) Not just finishing up a search + * 3) flush timer is empty + */ } else { if ((!update_lq) && (!done_search) && (!lq_data->flush_timer)) lq_data->flush_timer = jiffies; @@ -1641,21 +1954,22 @@ out: } -static void rs_initialize_lq(struct iwl_priv *priv, +static void rs_initialize_lq(struct iwl4965_priv *priv, + struct ieee80211_conf *conf, struct sta_info *sta) { int i; - struct iwl_rate_scale_priv *lq; - struct iwl_scale_tbl_info *tbl; + struct iwl4965_rate_scale_priv *lq; + struct iwl4965_scale_tbl_info *tbl; u8 active_tbl = 0; int rate_idx; - u8 use_green = rs_use_green(priv); - struct iwl_rate mcs_rate; + u8 use_green = rs_use_green(priv, conf); + struct iwl4965_rate mcs_rate; if (!sta || !sta->rate_ctrl_priv) goto out; - lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv; + lq = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; i = sta->last_txrate; if ((lq->lq.sta_id == 0xff) && @@ -1672,7 +1986,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, if ((i < 0) || (i >= IWL_RATE_COUNT)) i = 0; - mcs_rate.rate_n_flags = iwl_rates[i].plcp ; + mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ; mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK; mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK; @@ -1718,11 +2032,12 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, int i; struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); + struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct sta_info *sta; u16 fc; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct iwl_rate_scale_priv *lq; + struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; + struct iwl4965_rate_scale_priv *lq; IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); @@ -1744,24 +2059,24 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, return rs_get_lowest_rate(local); } - lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv; + lq = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; i = sta->last_txrate; if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added) { - u8 sta_id = iwl_hw_find_station(priv, hdr->addr1); + u8 sta_id = iwl4965_hw_find_station(priv, hdr->addr1); DECLARE_MAC_BUF(mac); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", print_mac(mac, hdr->addr1)); - sta_id = iwl_add_station(priv, - hdr->addr1, 0, CMD_ASYNC); + sta_id = iwl4965_add_station_flags(priv, hdr->addr1, + 0, CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { lq->lq.sta_id = sta_id; lq->lq.rs_table[0].rate_n_flags = 0; lq->ibss_sta_added = 1; - rs_initialize_lq(priv, sta); + rs_initialize_lq(priv, conf, sta); } if (!lq->ibss_sta_added) goto done; @@ -1777,12 +2092,12 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate, static void *rs_alloc_sta(void *priv, gfp_t gfp) { - struct iwl_rate_scale_priv *crl; + struct iwl4965_rate_scale_priv *crl; int i, j; IWL_DEBUG_RATE("create station rate scale window\n"); - crl = kzalloc(sizeof(struct iwl_rate_scale_priv), gfp); + crl = kzalloc(sizeof(struct iwl4965_rate_scale_priv), gfp); if (crl == NULL) return NULL; @@ -1801,9 +2116,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, struct sta_info *sta) { int i, j; + struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_hw_mode *mode = local->oper_hw_mode; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct iwl_rate_scale_priv *crl = priv_sta; + struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; + struct iwl4965_rate_scale_priv *crl = priv_sta; crl->flush_timer = 0; crl->supp_rates = sta->supp_rates; @@ -1820,7 +2136,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, crl->ibss_sta_added = 0; if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { - u8 sta_id = iwl_hw_find_station(priv, sta->addr); + u8 sta_id = iwl4965_hw_find_station(priv, sta->addr); DECLARE_MAC_BUF(mac); /* for IBSS the call are from tasklet */ @@ -1830,8 +2146,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", print_mac(mac, sta->addr)); - sta_id = iwl_add_station(priv, - sta->addr, 0, CMD_ASYNC); + sta_id = iwl4965_add_station_flags(priv, sta->addr, + 0, CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { crl->lq.sta_id = sta_id; @@ -1841,39 +2157,45 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, priv->assoc_station_added = 1; } + /* Find highest tx rate supported by hardware and destination station */ for (i = 0; i < mode->num_rates; i++) { if ((sta->supp_rates & BIT(i)) && (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) sta->txrate = i; } sta->last_txrate = sta->txrate; - /* For MODE_IEEE80211A mode cck rate are at end - * rate table - */ + /* For MODE_IEEE80211A, cck rates are at end of rate table */ if (local->hw.conf.phymode == MODE_IEEE80211A) sta->last_txrate += IWL_FIRST_OFDM_RATE; - crl->is_dup = priv->is_dup; + crl->is_dup = 0; crl->valid_antenna = priv->valid_antenna; crl->antenna = priv->antenna; - crl->is_green = rs_use_green(priv); + crl->is_green = rs_use_green(priv, conf); crl->active_rate = priv->active_rate; crl->active_rate &= ~(0x1000); crl->active_rate_basic = priv->active_rate_basic; crl->phymode = priv->phymode; -#ifdef CONFIG_IWLWIFI_HT - crl->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1); - crl->active_siso_rate |= (priv->current_assoc_ht.supp_rates[0] & 0x1); +#ifdef CONFIG_IWL4965_HT + /* + * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), + * supp_rates[] does not; shift to convert format, force 9 MBits off. + */ + crl->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0] << 1); + crl->active_siso_rate |= + (priv->current_ht_config.supp_mcs_set[0] & 0x1); crl->active_siso_rate &= ~((u16)0x2); crl->active_siso_rate = crl->active_siso_rate << IWL_FIRST_OFDM_RATE; - crl->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1); - crl->active_mimo_rate |= (priv->current_assoc_ht.supp_rates[1] & 0x1); + /* Same here */ + crl->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1] << 1); + crl->active_mimo_rate |= + (priv->current_ht_config.supp_mcs_set[1] & 0x1); crl->active_mimo_rate &= ~((u16)0x2); crl->active_mimo_rate = crl->active_mimo_rate << IWL_FIRST_OFDM_RATE; IWL_DEBUG_HT("MIMO RATE 0x%X SISO MASK 0x%X\n", crl->active_siso_rate, crl->active_mimo_rate); -#endif /*CONFIG_IWLWIFI_HT*/ +#endif /*CONFIG_IWL4965_HT*/ #ifdef CONFIG_MAC80211_DEBUGFS crl->drv = priv; #endif @@ -1881,26 +2203,29 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, if (priv->assoc_station_added) priv->lq_mngr.lq_ready = 1; - rs_initialize_lq(priv, sta); + rs_initialize_lq(priv, conf, sta); } -static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, - struct iwl_rate *tx_mcs, - struct iwl_link_quality_cmd *lq_cmd) +static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data, + struct iwl4965_rate *tx_mcs, + struct iwl4965_link_quality_cmd *lq_cmd) { int index = 0; int rate_idx; int repeat_rate = 0; u8 ant_toggle_count = 0; u8 use_ht_possible = 1; - struct iwl_rate new_rate; - struct iwl_scale_tbl_info tbl_type = { 0 }; + struct iwl4965_rate new_rate; + struct iwl4965_scale_tbl_info tbl_type = { 0 }; + /* Override starting rate (index 0) if needed for debug purposes */ rs_dbgfs_set_mcs(lq_data, tx_mcs, index); + /* Interpret rate_n_flags */ rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode, &tbl_type, &rate_idx); + /* How many times should we repeat the initial rate? */ if (is_legacy(tbl_type.lq_type)) { ant_toggle_count = 1; repeat_rate = IWL_NUMBER_TRY; @@ -1909,19 +2234,27 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, lq_cmd->general_params.mimo_delimiter = is_mimo(tbl_type.lq_type) ? 1 : 0; + + /* Fill 1st table entry (index 0) */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(tx_mcs->rate_n_flags); new_rate.rate_n_flags = tx_mcs->rate_n_flags; if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN)) - lq_cmd->general_params.single_stream_ant_msk = 1; + lq_cmd->general_params.single_stream_ant_msk + = LINK_QUAL_ANT_A_MSK; else - lq_cmd->general_params.single_stream_ant_msk = 2; + lq_cmd->general_params.single_stream_ant_msk + = LINK_QUAL_ANT_B_MSK; index++; repeat_rate--; + /* Fill rest of rate table */ while (index < LINK_QUAL_MAX_RETRY_NUM) { + /* Repeat initial/next rate. + * For legacy IWL_NUMBER_TRY == 1, this loop will not execute. + * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */ while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { if (is_legacy(tbl_type.lq_type)) { if (ant_toggle_count < @@ -1933,7 +2266,10 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, } } + /* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs(lq_data, &new_rate, index); + + /* Fill next table entry */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate.rate_n_flags); repeat_rate--; @@ -1943,12 +2279,17 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, rs_get_tbl_info_from_mcs(&new_rate, lq_data->phymode, &tbl_type, &rate_idx); + /* 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. */ if (is_mimo(tbl_type.lq_type)) lq_cmd->general_params.mimo_delimiter = index; + /* Get next rate */ rs_get_lower_rate(lq_data, &tbl_type, rate_idx, use_ht_possible, &new_rate); + /* How many times should we repeat the next rate? */ if (is_legacy(tbl_type.lq_type)) { if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE) ant_toggle_count++; @@ -1960,9 +2301,14 @@ static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data, } else repeat_rate = IWL_HT_NUMBER_TRY; + /* Don't allow HT rates after next pass. + * rs_get_lower_rate() will change type to LQ_A or LQ_G. */ use_ht_possible = 0; + /* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs(lq_data, &new_rate, index); + + /* Fill next table entry */ lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate.rate_n_flags); @@ -1987,24 +2333,24 @@ static void rs_free(void *priv_rate) static void rs_clear(void *priv_rate) { - struct iwl_priv *priv = (struct iwl_priv *) priv_rate; + struct iwl4965_priv *priv = (struct iwl4965_priv *) priv_rate; IWL_DEBUG_RATE("enter\n"); priv->lq_mngr.lq_ready = 0; -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG if (priv->lq_mngr.agg_ctrl.granted_ba) iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED); -#endif /*CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ IWL_DEBUG_RATE("leave\n"); } static void rs_free_sta(void *priv, void *priv_sta) { - struct iwl_rate_scale_priv *rs_priv = priv_sta; + struct iwl4965_rate_scale_priv *rs_priv = priv_sta; IWL_DEBUG_RATE("enter\n"); kfree(rs_priv); @@ -2018,8 +2364,8 @@ static int open_file_generic(struct inode *inode, struct file *file) file->private_data = inode->i_private; return 0; } -static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv, - struct iwl_rate *mcs, int index) +static void rs_dbgfs_set_mcs(struct iwl4965_rate_scale_priv *rs_priv, + struct iwl4965_rate *mcs, int index) { u32 base_rate; @@ -2043,7 +2389,7 @@ static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv, static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - struct iwl_rate_scale_priv *rs_priv = file->private_data; + struct iwl4965_rate_scale_priv *rs_priv = file->private_data; char buf[64]; int buf_size; u32 parsed_rate; @@ -2058,9 +2404,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, else rs_priv->dbg_fixed.rate_n_flags = 0; - rs_priv->active_rate = 0x0FFF; - rs_priv->active_siso_rate = 0x1FD0; - rs_priv->active_mimo_rate = 0x1FD0; + rs_priv->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ + rs_priv->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ + rs_priv->active_mimo_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags); @@ -2080,7 +2426,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, int desc = 0; int i = 0; - struct iwl_rate_scale_priv *rs_priv = file->private_data; + struct iwl4965_rate_scale_priv *rs_priv = file->private_data; desc += sprintf(buff+desc, "sta_id %d\n", rs_priv->lq.sta_id); desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", @@ -2128,7 +2474,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, int desc = 0; int i, j; - struct iwl_rate_scale_priv *rs_priv = file->private_data; + struct iwl4965_rate_scale_priv *rs_priv = file->private_data; for (i = 0; i < LQ_SIZE; i++) { desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n" "rate=0x%X\n", @@ -2157,7 +2503,7 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = { static void rs_add_debugfs(void *priv, void *priv_sta, struct dentry *dir) { - struct iwl_rate_scale_priv *rs_priv = priv_sta; + struct iwl4965_rate_scale_priv *rs_priv = priv_sta; rs_priv->rs_sta_dbgfs_scale_table_file = debugfs_create_file("rate_scale_table", 0600, dir, rs_priv, &rs_sta_dbgfs_scale_table_ops); @@ -2168,7 +2514,7 @@ static void rs_add_debugfs(void *priv, void *priv_sta, static void rs_remove_debugfs(void *priv, void *priv_sta) { - struct iwl_rate_scale_priv *rs_priv = priv_sta; + struct iwl4965_rate_scale_priv *rs_priv = priv_sta; debugfs_remove(rs_priv->rs_sta_dbgfs_scale_table_file); debugfs_remove(rs_priv->rs_sta_dbgfs_stats_table_file); } @@ -2191,11 +2537,11 @@ static struct rate_control_ops rs_ops = { #endif }; -int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) +int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) { struct ieee80211_local *local = hw_to_local(hw); - struct iwl_priv *priv = hw->priv; - struct iwl_rate_scale_priv *rs_priv; + struct iwl4965_priv *priv = hw->priv; + struct iwl4965_rate_scale_priv *rs_priv; struct sta_info *sta; int count = 0, i; u32 samples = 0, success = 0, good = 0; @@ -2228,7 +2574,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) int active = rs_priv->active_tbl; count += - sprintf(&buf[count], " %2dMbs: ", iwl_rates[i].ieee / 2); + sprintf(&buf[count], " %2dMbs: ", iwl4965_rates[i].ieee / 2); mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1)); for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1) @@ -2239,7 +2585,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) samples += rs_priv->lq_info[active].win[i].counter; good += rs_priv->lq_info[active].win[i].success_counter; success += rs_priv->lq_info[active].win[i].success_counter * - iwl_rates[i].ieee; + iwl4965_rates[i].ieee; if (rs_priv->lq_info[active].win[i].stamp) { int delta = @@ -2253,7 +2599,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) } else buf[count++] = '\n'; - j = iwl_get_prev_ieee_rate(i); + j = iwl4965_get_prev_ieee_rate(i); if (j == i) break; i = j; @@ -2261,8 +2607,8 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) /* Display the average rate of all samples taken. * - * NOTE: We multiple # of samples by 2 since the IEEE measurement - * added from iwl_rates is actually 2X the rate */ + * NOTE: We multiply # of samples by 2 since the IEEE measurement + * added from iwl4965_rates is actually 2X the rate */ if (samples) count += sprintf(&buf[count], "\nAverage rate is %3d.%02dMbs over last %4dms\n" @@ -2271,7 +2617,7 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) max_time, good * 100 / samples, good, samples); else count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n"); - count += sprintf(&buf[count], "\nrate scale type %d anntena %d " + count += sprintf(&buf[count], "\nrate scale type %d antenna %d " "active_search %d rate index %d\n", lq_type, antenna, rs_priv->search_better_tbl, sta->last_txrate); @@ -2279,19 +2625,19 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) return count; } -void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) +void iwl4965_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; priv->lq_mngr.lq_ready = 1; } -void iwl_rate_control_register(struct ieee80211_hw *hw) +void iwl4965_rate_control_register(struct ieee80211_hw *hw) { ieee80211_rate_control_register(&rs_ops); } -void iwl_rate_control_unregister(struct ieee80211_hw *hw) +void iwl4965_rate_control_unregister(struct ieee80211_hw *hw) { ieee80211_rate_control_unregister(&rs_ops); } diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index c6325f7..31e21e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h @@ -29,11 +29,11 @@ #include "iwl-4965.h" -struct iwl_rate_info { - u8 plcp; - u8 plcp_siso; - u8 plcp_mimo; - u8 ieee; +struct iwl4965_rate_info { + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ + u8 plcp_mimo; /* uCode API: IWL_RATE_MIMO_6M_PLCP, etc. */ + u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ u8 prev_ieee; /* previous rate in IEEE speeds */ u8 next_ieee; /* next rate in IEEE speeds */ u8 prev_rs; /* previous rate used in rs algo */ @@ -42,6 +42,10 @@ struct iwl_rate_info { u8 next_rs_tgg; /* next rate used in TGG rs algo */ }; +/* + * These serve as indexes into + * struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; + */ enum { IWL_RATE_1M_INDEX = 0, IWL_RATE_2M_INDEX, @@ -83,6 +87,7 @@ enum { #define IWL_RATE_5M_MASK (1< #include -#define IWL 4965 - -#include "iwlwifi.h" #include "iwl-4965.h" #include "iwl-helpers.h" +static void iwl4965_hw_card_show_info(struct iwl4965_priv *priv); + #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, \ @@ -63,7 +62,7 @@ * maps to IWL_RATE_INVALID * */ -const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { +const struct iwl4965_rate_info iwl4965_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 */ @@ -85,16 +84,16 @@ static int is_fat_channel(__le32 rxon_flags) (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); } -static u8 is_single_stream(struct iwl_priv *priv) +static u8 is_single_stream(struct iwl4965_priv *priv) { -#ifdef CONFIG_IWLWIFI_HT - if (!priv->is_ht_enabled || !priv->current_assoc_ht.is_ht || - (priv->active_rate_ht[1] == 0) || +#ifdef CONFIG_IWL4965_HT + if (!priv->current_ht_config.is_ht || + (priv->current_ht_config.supp_mcs_set[1] == 0) || (priv->ps_mode == IWL_MIMO_PS_STATIC)) return 1; #else return 1; -#endif /*CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT */ return 0; } @@ -104,7 +103,7 @@ static u8 is_single_stream(struct iwl_priv *priv) * 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 iwl4965_get_rx_chain_counter(struct iwl_priv *priv, +static int iwl4965_get_rx_chain_counter(struct iwl4965_priv *priv, u8 *idle_state, u8 *rx_state) { u8 is_single = is_single_stream(priv); @@ -133,32 +132,32 @@ static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv, return 0; } -int iwl_hw_rxq_stop(struct iwl_priv *priv) +int iwl4965_hw_rxq_stop(struct iwl4965_priv *priv) { int rc; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - /* stop HW */ - iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - rc = iwl_poll_restricted_bit(priv, FH_MEM_RSSR_RX_STATUS_REG, + /* stop Rx DMA */ + iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + rc = iwl4965_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG, (1 << 24), 1000); if (rc < 0) IWL_ERROR("Can't stop Rx DMA.\n"); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) +u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *addr) { int i; int start = 0; @@ -190,104 +189,114 @@ u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *addr) return ret; } -static int iwl4965_nic_set_pwr_src(struct iwl_priv *priv, int pwr_max) +static int iwl4965_nic_set_pwr_src(struct iwl4965_priv *priv, int pwr_max) { - int rc = 0; + int ret; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); - if (rc) { + ret = iwl4965_grab_nic_access(priv); + if (ret) { spin_unlock_irqrestore(&priv->lock, flags); - return rc; + return ret; } if (!pwr_max) { u32 val; - rc = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE, + ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE, &val); if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) - iwl_set_bits_mask_restricted_reg( - priv, APMG_PS_CTRL_REG, + iwl4965_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_restricted_reg( - priv, APMG_PS_CTRL_REG, + iwl4965_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~APMG_PS_CTRL_MSK_PWR_SRC); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); - return rc; + return ret; } -static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +static int iwl4965_rx_init(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq) { int rc; unsigned long flags; + unsigned int rb_size; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - /* stop HW */ - iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + if (iwl4965_param_amsdu_size_8K) + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; + else + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; + + /* Stop Rx DMA */ + iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + + /* Reset driver's Rx queue write index */ + iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); - iwl_write_restricted(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); - iwl_write_restricted(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, + /* Tell device where to find RBD circular buffer in DRAM */ + iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, rxq->dma_addr >> 8); - iwl_write_restricted(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, + /* Tell device where in DRAM to update its Rx status */ + iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, (priv->hw_setting.shared_phys + - offsetof(struct iwl_shared, val0)) >> 4); + offsetof(struct iwl4965_shared, val0)) >> 4); - iwl_write_restricted(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, + /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ + iwl4965_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | - IWL_FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K | + rb_size | /*0x10 << 4 | */ (RX_QUEUE_SIZE_LOG << FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); /* - * iwl_write32(priv,CSR_INT_COAL_REG,0); + * iwl4965_write32(priv,CSR_INT_COAL_REG,0); */ - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -static int iwl4965_kw_init(struct iwl_priv *priv) +/* Tell 4965 where to find the "keep warm" buffer */ +static int iwl4965_kw_init(struct iwl4965_priv *priv) { unsigned long flags; int rc; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) goto out; - iwl_write_restricted(priv, IWL_FH_KW_MEM_ADDR_REG, + iwl4965_write_direct32(priv, IWL_FH_KW_MEM_ADDR_REG, priv->kw.dma_addr >> 4); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); out: spin_unlock_irqrestore(&priv->lock, flags); return rc; } -static int iwl4965_kw_alloc(struct iwl_priv *priv) +static int iwl4965_kw_alloc(struct iwl4965_priv *priv) { struct pci_dev *dev = priv->pci_dev; - struct iwl_kw *kw = &priv->kw; + struct iwl4965_kw *kw = &priv->kw; kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); @@ -300,14 +309,19 @@ static int iwl4965_kw_alloc(struct iwl_priv *priv) #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") -int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode, u16 channel, - const struct iwl_eeprom_channel *eeprom_ch, +/** + * iwl4965_set_fat_chan_info - Copy fat channel info into driver's priv. + * + * Does not set up a command, or touch hardware. + */ +int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel, + const struct iwl4965_eeprom_channel *eeprom_ch, u8 fat_extension_channel) { - struct iwl_channel_info *ch_info; + struct iwl4965_channel_info *ch_info; - ch_info = (struct iwl_channel_info *) - iwl_get_channel_info(priv, phymode, channel); + ch_info = (struct iwl4965_channel_info *) + iwl4965_get_channel_info(priv, phymode, channel); if (!is_channel_valid(ch_info)) return -1; @@ -340,10 +354,13 @@ int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode, u16 channel, return 0; } -static void iwl4965_kw_free(struct iwl_priv *priv) +/** + * iwl4965_kw_free - Free the "keep warm" buffer + */ +static void iwl4965_kw_free(struct iwl4965_priv *priv) { struct pci_dev *dev = priv->pci_dev; - struct iwl_kw *kw = &priv->kw; + struct iwl4965_kw *kw = &priv->kw; if (kw->v_addr) { pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); @@ -358,7 +375,7 @@ static void iwl4965_kw_free(struct iwl_priv *priv) * @param priv * @return error code */ -static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) +static int iwl4965_txq_ctx_reset(struct iwl4965_priv *priv) { int rc = 0; int txq_id, slots_num; @@ -366,9 +383,10 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) iwl4965_kw_free(priv); - iwl_hw_txq_ctx_free(priv); + /* Free all tx/cmd queues and keep-warm buffer */ + iwl4965_hw_txq_ctx_free(priv); - /* Tx CMD queue */ + /* Alloc keep-warm buffer */ rc = iwl4965_kw_alloc(priv); if (rc) { IWL_ERROR("Keep Warm allocation failed"); @@ -377,28 +395,31 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (unlikely(rc)) { IWL_ERROR("TX reset failed"); spin_unlock_irqrestore(&priv->lock, flags); goto error_reset; } - iwl_write_restricted_reg(priv, SCD_TXFACT, 0); - iwl_release_restricted_access(priv); + /* Turn off all Tx DMA channels */ + iwl4965_write_prph(priv, KDR_SCD_TXFACT, 0); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); + /* Tell 4965 where to find the keep-warm buffer */ rc = iwl4965_kw_init(priv); if (rc) { IWL_ERROR("kw_init failed\n"); goto error_reset; } - /* Tx queue(s) */ + /* Alloc and init all (default 16) Tx queues, + * including the command queue (#4) */ for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) { slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, + rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); if (rc) { IWL_ERROR("Tx %d queue init failed\n", txq_id); @@ -409,32 +430,32 @@ static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) return rc; error: - iwl_hw_txq_ctx_free(priv); + iwl4965_hw_txq_ctx_free(priv); error_reset: iwl4965_kw_free(priv); error_kw: return rc; } -int iwl_hw_nic_init(struct iwl_priv *priv) +int iwl4965_hw_nic_init(struct iwl4965_priv *priv) { int rc; unsigned long flags; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl4965_rx_queue *rxq = &priv->rxq; u8 rev_id; u32 val; u8 val_link; - iwl_power_init_handle(priv); + iwl4965_power_init_handle(priv); /* nic_init */ spin_lock_irqsave(&priv->lock, flags); - iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS, + iwl4965_set_bit(priv, CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); - iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - rc = iwl_poll_bit(priv, CSR_GP_CNTRL, + iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + rc = iwl4965_poll_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (rc < 0) { @@ -443,26 +464,26 @@ int iwl_hw_nic_init(struct iwl_priv *priv) return rc; } - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_read_restricted_reg(priv, APMG_CLK_CTRL_REG); + iwl4965_read_prph(priv, APMG_CLK_CTRL_REG); - iwl_write_restricted_reg(priv, APMG_CLK_CTRL_REG, + iwl4965_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); - iwl_read_restricted_reg(priv, APMG_CLK_CTRL_REG); + iwl4965_read_prph(priv, APMG_CLK_CTRL_REG); udelay(20); - iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG, + iwl4965_set_bits_prph(priv, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - iwl_release_restricted_access(priv); - iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); + iwl4965_release_nic_access(priv); + iwl4965_write32(priv, CSR_INT_COALESCING, 512 / 32); spin_unlock_irqrestore(&priv->lock, flags); /* Determine HW type */ @@ -485,7 +506,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); /* Read the EEPROM */ - rc = iwl_eeprom_init(priv); + rc = iwl4965_eeprom_init(priv); if (rc) return rc; @@ -503,51 +524,53 @@ int iwl_hw_nic_init(struct iwl_priv *priv) /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | + iwl4965_set_bit(priv, CSR_SW_VER, CSR_HW_IF_CONFIG_REG_BIT_KEDRON_R | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc < 0) { spin_unlock_irqrestore(&priv->lock, flags); IWL_DEBUG_INFO("Failed to init the card\n"); return rc; } - iwl_read_restricted_reg(priv, APMG_PS_CTRL_REG); - iwl_set_bits_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl4965_read_prph(priv, APMG_PS_CTRL_REG); + iwl4965_set_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); - iwl_clear_bits_restricted_reg(priv, APMG_PS_CTRL_REG, + iwl4965_clear_bits_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); - iwl_hw_card_show_info(priv); + iwl4965_hw_card_show_info(priv); /* end nic_init */ /* Allocate the RX queue, or reset if it is already allocated */ if (!rxq->bd) { - rc = iwl_rx_queue_alloc(priv); + rc = iwl4965_rx_queue_alloc(priv); if (rc) { IWL_ERROR("Unable to initialize Rx queue\n"); return -ENOMEM; } } else - iwl_rx_queue_reset(priv, rxq); + iwl4965_rx_queue_reset(priv, rxq); - iwl_rx_replenish(priv); + iwl4965_rx_replenish(priv); iwl4965_rx_init(priv, rxq); spin_lock_irqsave(&priv->lock, flags); rxq->need_update = 1; - iwl_rx_queue_update_write_ptr(priv, rxq); + iwl4965_rx_queue_update_write_ptr(priv, rxq); spin_unlock_irqrestore(&priv->lock, flags); + + /* Allocate and init all Tx and Command queues */ rc = iwl4965_txq_ctx_reset(priv); if (rc) return rc; @@ -563,7 +586,7 @@ int iwl_hw_nic_init(struct iwl_priv *priv) return 0; } -int iwl_hw_nic_stop_master(struct iwl_priv *priv) +int iwl4965_hw_nic_stop_master(struct iwl4965_priv *priv) { int rc = 0; u32 reg_val; @@ -572,16 +595,16 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); /* set stop master bit */ - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - reg_val = iwl_read32(priv, CSR_GP_CNTRL); + reg_val = iwl4965_read32(priv, CSR_GP_CNTRL); if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE == (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE)) IWL_DEBUG_INFO("Card in power save, master is already " "stopped\n"); else { - rc = iwl_poll_bit(priv, CSR_RESET, + rc = iwl4965_poll_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (rc < 0) { @@ -596,65 +619,69 @@ int iwl_hw_nic_stop_master(struct iwl_priv *priv) return rc; } -void iwl_hw_txq_ctx_stop(struct iwl_priv *priv) +/** + * iwl4965_hw_txq_ctx_stop - Stop all Tx DMA channels, free Tx queue memory + */ +void iwl4965_hw_txq_ctx_stop(struct iwl4965_priv *priv) { int txq_id; unsigned long flags; - /* reset TFD queues */ + /* Stop each Tx DMA channel, and wait for it to be idle */ for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) { spin_lock_irqsave(&priv->lock, flags); - if (iwl_grab_restricted_access(priv)) { + if (iwl4965_grab_nic_access(priv)) { spin_unlock_irqrestore(&priv->lock, flags); continue; } - iwl_write_restricted(priv, + iwl4965_write_direct32(priv, IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), 0x0); - iwl_poll_restricted_bit(priv, IWL_FH_TSSR_TX_STATUS_REG, + iwl4965_poll_direct_bit(priv, IWL_FH_TSSR_TX_STATUS_REG, IWL_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE (txq_id), 200); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); } - iwl_hw_txq_ctx_free(priv); + /* Deallocate memory for all Tx queues */ + iwl4965_hw_txq_ctx_free(priv); } -int iwl_hw_nic_reset(struct iwl_priv *priv) +int iwl4965_hw_nic_reset(struct iwl4965_priv *priv) { int rc = 0; unsigned long flags; - iwl_hw_nic_stop_master(priv); + iwl4965_hw_nic_stop_master(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); udelay(10); - iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - rc = iwl_poll_bit(priv, CSR_RESET, + iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + rc = iwl4965_poll_bit(priv, CSR_RESET, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25); udelay(10); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (!rc) { - iwl_write_restricted_reg(priv, APMG_CLK_EN_REG, + iwl4965_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); udelay(10); - iwl_set_bits_restricted_reg(priv, APMG_PCIDEV_STT_REG, + iwl4965_set_bits_prph(priv, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } clear_bit(STATUS_HCMD_ACTIVE, &priv->status); @@ -684,7 +711,7 @@ int iwl_hw_nic_reset(struct iwl_priv *priv) */ static void iwl4965_bg_statistics_periodic(unsigned long data) { - struct iwl_priv *priv = (struct iwl_priv *)data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)data; queue_work(priv->workqueue, &priv->statistics_work); } @@ -692,27 +719,27 @@ static void iwl4965_bg_statistics_periodic(unsigned long data) /** * iwl4965_bg_statistics_work - Send the statistics request to the hardware. * - * This is queued by iwl_bg_statistics_periodic. + * This is queued by iwl4965_bg_statistics_periodic. */ static void iwl4965_bg_statistics_work(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, statistics_work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_send_statistics_request(priv); + iwl4965_send_statistics_request(priv); mutex_unlock(&priv->mutex); } #define CT_LIMIT_CONST 259 #define TM_CT_KILL_THRESHOLD 110 -void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) +void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv) { - struct iwl_ct_kill_config cmd; + struct iwl4965_ct_kill_config cmd; u32 R1, R2, R3; u32 temp_th; u32 crit_temperature; @@ -720,7 +747,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) int rc = 0; spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); spin_unlock_irqrestore(&priv->lock, flags); @@ -738,7 +765,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) crit_temperature = ((temp_th * (R3-R1))/CT_LIMIT_CONST) + R2; cmd.critical_temperature_R = cpu_to_le32(crit_temperature); - rc = iwl_send_cmd_pdu(priv, + rc = iwl4965_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, sizeof(cmd), &cmd); if (rc) IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); @@ -746,7 +773,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded\n"); } -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY /* "false alarms" are signals that our DSP tries to lock onto, * but then determines that they are either noise, or transmissions @@ -756,7 +783,7 @@ void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) * enough to receive all of our own network traffic, but not so * high that our DSP gets too busy trying to lock onto non-network * activity/noise. */ -static int iwl4965_sens_energy_cck(struct iwl_priv *priv, +static int iwl4965_sens_energy_cck(struct iwl4965_priv *priv, u32 norm_fa, u32 rx_enable_time, struct statistics_general_data *rx_info) @@ -782,7 +809,7 @@ static int iwl4965_sens_energy_cck(struct iwl_priv *priv, u32 false_alarms = norm_fa * 200 * 1024; u32 max_false_alarms = MAX_FA_CCK * rx_enable_time; u32 min_false_alarms = MIN_FA_CCK * rx_enable_time; - struct iwl_sensitivity_data *data = NULL; + struct iwl4965_sensitivity_data *data = NULL; data = &(priv->sensitivity_data); @@ -947,7 +974,7 @@ static int iwl4965_sens_energy_cck(struct iwl_priv *priv, } -static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv, +static int iwl4965_sens_auto_corr_ofdm(struct iwl4965_priv *priv, u32 norm_fa, u32 rx_enable_time) { @@ -955,7 +982,7 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv, u32 false_alarms = norm_fa * 200 * 1024; u32 max_false_alarms = MAX_FA_OFDM * rx_enable_time; u32 min_false_alarms = MIN_FA_OFDM * rx_enable_time; - struct iwl_sensitivity_data *data = NULL; + struct iwl4965_sensitivity_data *data = NULL; data = &(priv->sensitivity_data); @@ -1012,22 +1039,22 @@ static int iwl4965_sens_auto_corr_ofdm(struct iwl_priv *priv, return 0; } -static int iwl_sensitivity_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, struct sk_buff *skb) +static int iwl4965_sensitivity_callback(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct sk_buff *skb) { /* We didn't cache the SKB; let the caller free it */ return 1; } /* Prepare a SENSITIVITY_CMD, send to uCode if values have changed */ -static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) +static int iwl4965_sensitivity_write(struct iwl4965_priv *priv, u8 flags) { int rc = 0; - struct iwl_sensitivity_cmd cmd ; - struct iwl_sensitivity_data *data = NULL; - struct iwl_host_cmd cmd_out = { + struct iwl4965_sensitivity_cmd cmd ; + struct iwl4965_sensitivity_data *data = NULL; + struct iwl4965_host_cmd cmd_out = { .id = SENSITIVITY_CMD, - .len = sizeof(struct iwl_sensitivity_cmd), + .len = sizeof(struct iwl4965_sensitivity_cmd), .meta.flags = flags, .data = &cmd, }; @@ -1071,10 +1098,11 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) data->auto_corr_cck, data->auto_corr_cck_mrc, data->nrg_th_cck); + /* Update uCode's "work" table, and copy it to DSP */ cmd.control = SENSITIVITY_CMD_CONTROL_WORK_TABLE; if (flags & CMD_ASYNC) - cmd_out.meta.u.callback = iwl_sensitivity_callback; + cmd_out.meta.u.callback = iwl4965_sensitivity_callback; /* Don't send command to uCode if nothing has changed */ if (!memcmp(&cmd.table[0], &(priv->sensitivity_tbl[0]), @@ -1087,7 +1115,7 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) memcpy(&(priv->sensitivity_tbl[0]), &(cmd.table[0]), sizeof(u16)*HD_TABLE_SIZE); - rc = iwl_send_cmd(priv, &cmd_out); + rc = iwl4965_send_cmd(priv, &cmd_out); if (!rc) { IWL_DEBUG_CALIB("SENSITIVITY_CMD succeeded\n"); return rc; @@ -1096,11 +1124,11 @@ static int iwl4965_sensitivity_write(struct iwl_priv *priv, u8 flags) return 0; } -void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) +void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, u8 force) { int rc = 0; int i; - struct iwl_sensitivity_data *data = NULL; + struct iwl4965_sensitivity_data *data = NULL; IWL_DEBUG_CALIB("Start iwl4965_init_sensitivity\n"); @@ -1110,7 +1138,7 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) /* Clear driver's sensitivity algo data */ data = &(priv->sensitivity_data); - memset(data, 0, sizeof(struct iwl_sensitivity_data)); + memset(data, 0, sizeof(struct iwl4965_sensitivity_data)); data->num_in_cck_no_fa = 0; data->nrg_curr_state = IWL_FA_TOO_MANY; @@ -1154,21 +1182,21 @@ void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, u8 force) /* Reset differential Rx gains in NIC to prepare for chain noise calibration. * Called after every association, but this runs only once! * ... once chain noise is calibrated the first time, it's good forever. */ -void iwl4965_chain_noise_reset(struct iwl_priv *priv) +void iwl4965_chain_noise_reset(struct iwl4965_priv *priv) { - struct iwl_chain_noise_data *data = NULL; + struct iwl4965_chain_noise_data *data = NULL; int rc = 0; data = &(priv->chain_noise_data); - if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { - struct iwl_calibration_cmd cmd; + if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl4965_is_associated(priv)) { + struct iwl4965_calibration_cmd cmd; memset(&cmd, 0, sizeof(cmd)); cmd.opCode = PHY_CALIBRATE_DIFF_GAIN_CMD; cmd.diff_gain_a = 0; cmd.diff_gain_b = 0; cmd.diff_gain_c = 0; - rc = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, sizeof(cmd), &cmd); msleep(4); data->state = IWL_CHAIN_NOISE_ACCUMULATE; @@ -1183,10 +1211,10 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv) * 1) Which antennas are connected. * 2) Differential rx gain settings to balance the 3 receivers. */ -static void iwl4965_noise_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *stat_resp) +static void iwl4965_noise_calibration(struct iwl4965_priv *priv, + struct iwl4965_notif_statistics *stat_resp) { - struct iwl_chain_noise_data *data = NULL; + struct iwl4965_chain_noise_data *data = NULL; int rc = 0; u32 chain_noise_a; @@ -1385,7 +1413,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, /* Differential gain gets sent to uCode only once */ if (!data->radio_write) { - struct iwl_calibration_cmd cmd; + struct iwl4965_calibration_cmd cmd; data->radio_write = 1; memset(&cmd, 0, sizeof(cmd)); @@ -1393,7 +1421,7 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, cmd.diff_gain_a = data->delta_gain_code[0]; cmd.diff_gain_b = data->delta_gain_code[1]; cmd.diff_gain_c = data->delta_gain_code[2]; - rc = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, + rc = iwl4965_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, sizeof(cmd), &cmd); if (rc) IWL_DEBUG_CALIB("fail sending cmd " @@ -1416,8 +1444,8 @@ static void iwl4965_noise_calibration(struct iwl_priv *priv, return; } -static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, - struct iwl_notif_statistics *resp) +static void iwl4965_sensitivity_calibration(struct iwl4965_priv *priv, + struct iwl4965_notif_statistics *resp) { int rc = 0; u32 rx_enable_time; @@ -1427,7 +1455,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, u32 bad_plcp_ofdm; u32 norm_fa_ofdm; u32 norm_fa_cck; - struct iwl_sensitivity_data *data = NULL; + struct iwl4965_sensitivity_data *data = NULL; struct statistics_rx_non_phy *rx_info = &(resp->rx.general); struct statistics_rx *statistics = &(resp->rx); unsigned long flags; @@ -1435,7 +1463,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, data = &(priv->sensitivity_data); - if (!iwl_is_associated(priv)) { + if (!iwl4965_is_associated(priv)) { IWL_DEBUG_CALIB("<< - not associated\n"); return; } @@ -1523,7 +1551,7 @@ static void iwl4965_sensitivity_calibration(struct iwl_priv *priv, static void iwl4965_bg_sensitivity_work(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, sensitivity_work); mutex_lock(&priv->mutex); @@ -1549,11 +1577,11 @@ static void iwl4965_bg_sensitivity_work(struct work_struct *work) mutex_unlock(&priv->mutex); return; } -#endif /*CONFIG_IWLWIFI_SENSITIVITY*/ +#endif /*CONFIG_IWL4965_SENSITIVITY*/ static void iwl4965_bg_txpower_work(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, txpower_work); /* If a scan happened to start before we got here @@ -1569,7 +1597,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) /* Regardless of if we are assocaited, we must reconfigure the * TX power since frames can be sent on non-radar channels while * not associated */ - iwl_hw_reg_send_txpower(priv); + iwl4965_hw_reg_send_txpower(priv); /* Update last_temperature to keep is_calib_needed from running * when it isn't needed... */ @@ -1581,24 +1609,31 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) /* * Acquire priv->lock before calling this function ! */ -static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index) +static void iwl4965_set_wr_ptrs(struct iwl4965_priv *priv, int txq_id, u32 index) { - iwl_write_restricted(priv, HBUS_TARG_WRPTR, + iwl4965_write_direct32(priv, HBUS_TARG_WRPTR, (index & 0xff) | (txq_id << 8)); - iwl_write_restricted_reg(priv, SCD_QUEUE_RDPTR(txq_id), index); + iwl4965_write_prph(priv, KDR_SCD_QUEUE_RDPTR(txq_id), index); } -/* - * Acquire priv->lock before calling this function ! +/** + * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue + * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed + * @scd_retry: (1) Indicates queue will be used in aggregation mode + * + * NOTE: Acquire priv->lock before calling this function ! */ -static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, - struct iwl_tx_queue *txq, +static void iwl4965_tx_queue_set_status(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, int tx_fifo_id, int scd_retry) { int txq_id = txq->q.id; + + /* Find out whether to activate Tx queue */ int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0; - iwl_write_restricted_reg(priv, SCD_QUEUE_STATUS_BITS(txq_id), + /* Set up and activate */ + iwl4965_write_prph(priv, KDR_SCD_QUEUE_STATUS_BITS(txq_id), (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | (scd_retry << SCD_QUEUE_STTS_REG_POS_WSL) | @@ -1608,7 +1643,7 @@ static void iwl4965_tx_queue_set_status(struct iwl_priv *priv, txq->sched_retry = scd_retry; IWL_DEBUG_INFO("%s %s Queue %d on AC %d\n", - active ? "Activete" : "Deactivate", + active ? "Activate" : "Deactivate", scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); } @@ -1622,17 +1657,17 @@ static const u16 default_queue_to_tx_fifo[] = { IWL_TX_FIFO_HCCA_2 }; -static inline void iwl4965_txq_ctx_activate(struct iwl_priv *priv, int txq_id) +static inline void iwl4965_txq_ctx_activate(struct iwl4965_priv *priv, int txq_id) { set_bit(txq_id, &priv->txq_ctx_active_msk); } -static inline void iwl4965_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id) +static inline void iwl4965_txq_ctx_deactivate(struct iwl4965_priv *priv, int txq_id) { clear_bit(txq_id, &priv->txq_ctx_active_msk); } -int iwl4965_alive_notify(struct iwl_priv *priv) +int iwl4965_alive_notify(struct iwl4965_priv *priv) { u32 a; int i = 0; @@ -1641,45 +1676,55 @@ int iwl4965_alive_notify(struct iwl_priv *priv) spin_lock_irqsave(&priv->lock, flags); -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY memset(&(priv->sensitivity_data), 0, - sizeof(struct iwl_sensitivity_data)); + sizeof(struct iwl4965_sensitivity_data)); memset(&(priv->chain_noise_data), 0, - sizeof(struct iwl_chain_noise_data)); + sizeof(struct iwl4965_chain_noise_data)); for (i = 0; i < NUM_RX_CHAINS; i++) priv->chain_noise_data.delta_gain_code[i] = CHAIN_NOISE_DELTA_GAIN_INIT_VAL; -#endif /* CONFIG_IWLWIFI_SENSITIVITY*/ - rc = iwl_grab_restricted_access(priv); +#endif /* CONFIG_IWL4965_SENSITIVITY*/ + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - priv->scd_base_addr = iwl_read_restricted_reg(priv, SCD_SRAM_BASE_ADDR); + /* Clear 4965's internal Tx Scheduler data base */ + priv->scd_base_addr = iwl4965_read_prph(priv, KDR_SCD_SRAM_BASE_ADDR); a = priv->scd_base_addr + SCD_CONTEXT_DATA_OFFSET; for (; a < priv->scd_base_addr + SCD_TX_STTS_BITMAP_OFFSET; a += 4) - iwl_write_restricted_mem(priv, a, 0); + iwl4965_write_targ_mem(priv, a, 0); for (; a < priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET; a += 4) - iwl_write_restricted_mem(priv, a, 0); + iwl4965_write_targ_mem(priv, a, 0); for (; a < sizeof(u16) * priv->hw_setting.max_txq_num; a += 4) - iwl_write_restricted_mem(priv, a, 0); + iwl4965_write_targ_mem(priv, a, 0); - iwl_write_restricted_reg(priv, SCD_DRAM_BASE_ADDR, + /* Tel 4965 where to find Tx byte count tables */ + iwl4965_write_prph(priv, KDR_SCD_DRAM_BASE_ADDR, (priv->hw_setting.shared_phys + - offsetof(struct iwl_shared, queues_byte_cnt_tbls)) >> 10); - iwl_write_restricted_reg(priv, SCD_QUEUECHAIN_SEL, 0); + offsetof(struct iwl4965_shared, queues_byte_cnt_tbls)) >> 10); + + /* Disable chain mode for all queues */ + iwl4965_write_prph(priv, KDR_SCD_QUEUECHAIN_SEL, 0); - /* initiate the queues */ + /* Initialize each Tx queue (including the command queue) */ for (i = 0; i < priv->hw_setting.max_txq_num; i++) { - iwl_write_restricted_reg(priv, SCD_QUEUE_RDPTR(i), 0); - iwl_write_restricted(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); - iwl_write_restricted_mem(priv, priv->scd_base_addr + + + /* TFD circular buffer read/write indexes */ + iwl4965_write_prph(priv, KDR_SCD_QUEUE_RDPTR(i), 0); + iwl4965_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8)); + + /* Max Tx Window size for Scheduler-ACK mode */ + iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i), (SCD_WIN_SIZE << SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - iwl_write_restricted_mem(priv, priv->scd_base_addr + + + /* Frame limit */ + iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i) + sizeof(u32), (SCD_FRAME_LIMIT << @@ -1687,87 +1732,98 @@ int iwl4965_alive_notify(struct iwl_priv *priv) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); } - iwl_write_restricted_reg(priv, SCD_INTERRUPT_MASK, + iwl4965_write_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << priv->hw_setting.max_txq_num) - 1); - iwl_write_restricted_reg(priv, SCD_TXFACT, + /* Activate all Tx DMA/FIFO channels */ + iwl4965_write_prph(priv, KDR_SCD_TXFACT, SCD_TXFACT_REG_TXFIFO_MASK(0, 7)); iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); - /* map qos queues to fifos one-to-one */ + + /* Map each Tx/cmd queue to its corresponding fifo */ for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { int ac = default_queue_to_tx_fifo[i]; iwl4965_txq_ctx_activate(priv, i); iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0); } - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -int iwl_hw_set_hw_setting(struct iwl_priv *priv) +/** + * iwl4965_hw_set_hw_setting + * + * Called when initializing driver + */ +int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv) { + /* Allocate area for Tx byte count tables and Rx queue status */ priv->hw_setting.shared_virt = pci_alloc_consistent(priv->pci_dev, - sizeof(struct iwl_shared), + sizeof(struct iwl4965_shared), &priv->hw_setting.shared_phys); if (!priv->hw_setting.shared_virt) return -1; - memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl_shared)); + memset(priv->hw_setting.shared_virt, 0, sizeof(struct iwl4965_shared)); - priv->hw_setting.max_txq_num = iwl_param_queues_num; + priv->hw_setting.max_txq_num = iwl4965_param_queues_num; priv->hw_setting.ac_queue_count = AC_NUM; - - priv->hw_setting.cck_flag = RATE_MCS_CCK_MSK; - priv->hw_setting.tx_cmd_len = sizeof(struct iwl_tx_cmd); + priv->hw_setting.tx_cmd_len = sizeof(struct iwl4965_tx_cmd); priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE; priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG; - + if (iwl4965_param_amsdu_size_8K) + priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_8K; + else + priv->hw_setting.rx_buf_size = IWL_RX_BUF_SIZE_4K; + priv->hw_setting.max_pkt_size = priv->hw_setting.rx_buf_size - 256; priv->hw_setting.max_stations = IWL4965_STATION_COUNT; priv->hw_setting.bcast_sta_id = IWL4965_BROADCAST_ID; return 0; } /** - * iwl_hw_txq_ctx_free - Free TXQ Context + * iwl4965_hw_txq_ctx_free - Free TXQ Context * * Destroy all TX DMA queues and structures */ -void iwl_hw_txq_ctx_free(struct iwl_priv *priv) +void iwl4965_hw_txq_ctx_free(struct iwl4965_priv *priv) { int txq_id; /* Tx queues */ for (txq_id = 0; txq_id < priv->hw_setting.max_txq_num; txq_id++) - iwl_tx_queue_free(priv, &priv->txq[txq_id]); + iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); + /* Keep-warm buffer */ iwl4965_kw_free(priv); } /** - * iwl_hw_txq_free_tfd - Free one TFD, those at index [txq->q.last_used] + * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * - * Does NOT advance any indexes + * Does NOT advance any TFD circular buffer read/write indexes + * Does NOT free the TFD itself (which is within circular buffer) */ -int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) +int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq) { - struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; - struct iwl_tfd_frame *bd = &bd_tmp[txq->q.last_used]; + struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0]; + struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; struct pci_dev *dev = priv->pci_dev; int i; int counter = 0; int index, is_odd; - /* classify bd */ + /* Host command buffers stay mapped in memory, nothing to clean */ if (txq->q.id == IWL_CMD_QUEUE_NUM) - /* nothing to cleanup after for host commands */ return 0; - /* sanity check */ + /* Sanity check on number of chunks */ counter = IWL_GET_BITS(*bd, num_tbs); if (counter > MAX_NUM_OF_TBS) { IWL_ERROR("Too many chunks: %i\n", counter); @@ -1775,8 +1831,8 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) return 0; } - /* unmap chunks if any */ - + /* Unmap chunks, if any. + * TFD info for odd chunks is different format than for even chunks. */ for (i = 0; i < counter; i++) { index = i / 2; is_odd = i & 0x1; @@ -1796,19 +1852,20 @@ int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) IWL_GET_BITS(bd->pa[index], tb1_len), PCI_DMA_TODEVICE); - if (txq->txb[txq->q.last_used].skb[i]) { - struct sk_buff *skb = txq->txb[txq->q.last_used].skb[i]; + /* Free SKB, if any, for this chunk */ + if (txq->txb[txq->q.read_ptr].skb[i]) { + struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; dev_kfree_skb(skb); - txq->txb[txq->q.last_used].skb[i] = NULL; + txq->txb[txq->q.read_ptr].skb[i] = NULL; } } return 0; } -int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) +int iwl4965_hw_reg_set_txpower(struct iwl4965_priv *priv, s8 power) { - IWL_ERROR("TODO: Implement iwl_hw_reg_set_txpower!\n"); + IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n"); return -EINVAL; } @@ -1830,6 +1887,17 @@ static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) return 1; } +/** + * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower + * + * Determines power supply voltage compensation for txpower calculations. + * Returns number of 1/2-dB steps to subtract from gain table index, + * to compensate for difference between power supply voltage during + * factory measurements, vs. current power supply voltage. + * + * Voltage indication is higher for lower voltage. + * Lower voltage requires more gain (lower gain table index). + */ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, s32 current_voltage) { @@ -1850,12 +1918,12 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, return comp; } -static const struct iwl_channel_info * -iwl4965_get_channel_txpower_info(struct iwl_priv *priv, u8 phymode, u16 channel) +static const struct iwl4965_channel_info * +iwl4965_get_channel_txpower_info(struct iwl4965_priv *priv, u8 phymode, u16 channel) { - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, phymode, channel); + ch_info = iwl4965_get_channel_info(priv, phymode, channel); if (!is_channel_valid(ch_info)) return NULL; @@ -1889,7 +1957,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel) return -1; } -static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) +static u32 iwl4965_get_sub_band(const struct iwl4965_priv *priv, u32 channel) { s32 b = -1; @@ -1917,15 +1985,23 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) } } -static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, - struct iwl_eeprom_calib_ch_info *chan_info) +/** + * iwl4965_interpolate_chan - Interpolate factory measurements for one channel + * + * Interpolates factory measurements from the two sample channels within a + * sub-band, to apply to channel of interest. Interpolation is proportional to + * differences in channel frequencies, which is proportional to differences + * in channel number. + */ +static int iwl4965_interpolate_chan(struct iwl4965_priv *priv, u32 channel, + struct iwl4965_eeprom_calib_ch_info *chan_info) { s32 s = -1; u32 c; u32 m; - const struct iwl_eeprom_calib_measure *m1; - const struct iwl_eeprom_calib_measure *m2; - struct iwl_eeprom_calib_measure *omeas; + const struct iwl4965_eeprom_calib_measure *m1; + const struct iwl4965_eeprom_calib_measure *m2; + struct iwl4965_eeprom_calib_measure *omeas; u32 ch_i1; u32 ch_i2; @@ -2000,7 +2076,7 @@ static s32 back_off_table[] = { /* Thermal compensation values for txpower for various frequency ranges ... * ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */ -static struct iwl_txpower_comp_entry { +static struct iwl4965_txpower_comp_entry { s32 degrees_per_05db_a; s32 degrees_per_05db_a_denom; } tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = { @@ -2250,9 +2326,9 @@ static const struct gain_entry gain_table[2][108] = { } }; -static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, +static int iwl4965_fill_txpower_tbl(struct iwl4965_priv *priv, u8 band, u16 channel, u8 is_fat, u8 ctrl_chan_high, - struct iwl_tx_power_db *tx_power_tbl) + struct iwl4965_tx_power_db *tx_power_tbl) { u8 saturation_power; s32 target_power; @@ -2264,9 +2340,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, s32 txatten_grp = CALIB_CH_GROUP_MAX; int i; int c; - const struct iwl_channel_info *ch_info = NULL; - struct iwl_eeprom_calib_ch_info ch_eeprom_info; - const struct iwl_eeprom_calib_measure *measurement; + const struct iwl4965_channel_info *ch_info = NULL; + struct iwl4965_eeprom_calib_ch_info ch_eeprom_info; + const struct iwl4965_eeprom_calib_measure *measurement; s16 voltage; s32 init_voltage; s32 voltage_compensation; @@ -2405,7 +2481,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, /* for each of 33 bit-rates (including 1 for CCK) */ for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) { u8 is_mimo_rate; - union iwl_tx_power_dual_stream tx_power; + union iwl4965_tx_power_dual_stream tx_power; /* for mimo, reduce each chain's txpower by half * (3dB, 6 steps), so total output power is regulatory @@ -2502,14 +2578,14 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, } /** - * iwl_hw_reg_send_txpower - Configure the TXPOWER level user limit + * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit * * Uses the active RXON for channel, band, and characteristics (fat, high) * The power limit is taken from priv->user_txpower_limit. */ -int iwl_hw_reg_send_txpower(struct iwl_priv *priv) +int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv) { - struct iwl_txpowertable_cmd cmd = { 0 }; + struct iwl4965_txpowertable_cmd cmd = { 0 }; int rc = 0; u8 band = 0; u8 is_fat = 0; @@ -2541,23 +2617,23 @@ int iwl_hw_reg_send_txpower(struct iwl_priv *priv) if (rc) return rc; - rc = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); + rc = iwl4965_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd); return rc; } -int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel) +int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel) { int rc; u8 band = 0; u8 is_fat = 0; u8 ctrl_chan_high = 0; - struct iwl_channel_switch_cmd cmd = { 0 }; - const struct iwl_channel_info *ch_info; + struct iwl4965_channel_switch_cmd cmd = { 0 }; + const struct iwl4965_channel_info *ch_info; band = ((priv->phymode == MODE_IEEE80211B) || (priv->phymode == MODE_IEEE80211G)); - ch_info = iwl_get_channel_info(priv, priv->phymode, channel); + ch_info = iwl4965_get_channel_info(priv, priv->phymode, channel); is_fat = is_fat_channel(priv->staging_rxon.flags); @@ -2583,15 +2659,15 @@ int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel) return rc; } - rc = iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); + rc = iwl4965_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); return rc; } #define RTS_HCCA_RETRY_LIMIT 3 #define RTS_DFAULT_RETRY_LIMIT 60 -void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_cmd *cmd, +void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct ieee80211_tx_control *ctrl, struct ieee80211_hdr *hdr, int sta_id, int is_hcca) @@ -2604,7 +2680,7 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, tx_flags = cmd->cmd.tx.tx_flags; - rate = iwl_rates[ctrl->tx_rate].plcp; + rate = iwl4965_rates[ctrl->tx_rate].plcp; rts_retry_limit = (is_hcca) ? RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT; @@ -2637,26 +2713,26 @@ void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, cmd->cmd.tx.rts_retry_limit = rts_retry_limit; cmd->cmd.tx.data_retry_limit = data_retry_limit; - cmd->cmd.tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate, 0); + cmd->cmd.tx.rate_n_flags = iwl4965_hw_set_rate_n_flags(rate, 0); cmd->cmd.tx.tx_flags = tx_flags; } -int iwl_hw_get_rx_read(struct iwl_priv *priv) +int iwl4965_hw_get_rx_read(struct iwl4965_priv *priv) { - struct iwl_shared *shared_data = priv->hw_setting.shared_virt; + struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; return IWL_GET_BITS(*shared_data, rb_closed_stts_rb_num); } -int iwl_hw_get_temperature(struct iwl_priv *priv) +int iwl4965_hw_get_temperature(struct iwl4965_priv *priv) { return priv->temperature; } -unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl_frame *frame, u8 rate) +unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv, + struct iwl4965_frame *frame, u8 rate) { - struct iwl_tx_beacon_cmd *tx_beacon_cmd; + struct iwl4965_tx_beacon_cmd *tx_beacon_cmd; unsigned int frame_size; tx_beacon_cmd = &frame->u.beacon; @@ -2665,9 +2741,9 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, tx_beacon_cmd->tx.sta_id = IWL4965_BROADCAST_ID; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - frame_size = iwl_fill_beacon_frame(priv, + frame_size = iwl4965_fill_beacon_frame(priv, tx_beacon_cmd->frame, - BROADCAST_ADDR, + iwl4965_broadcast_addr, sizeof(frame->u) - sizeof(*tx_beacon_cmd)); BUG_ON(frame_size > MAX_MPDU_SIZE); @@ -2675,36 +2751,46 @@ unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) tx_beacon_cmd->tx.rate_n_flags = - iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); + iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); else tx_beacon_cmd->tx.rate_n_flags = - iwl_hw_set_rate_n_flags(rate, 0); + iwl4965_hw_set_rate_n_flags(rate, 0); tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK); return (sizeof(*tx_beacon_cmd) + frame_size); } -int iwl_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq) +/* + * Tell 4965 where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * + * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA + * channels supported in hardware. + */ +int iwl4965_hw_tx_queue_init(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq) { int rc; unsigned long flags; int txq_id = txq->q.id; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } - iwl_write_restricted(priv, FH_MEM_CBBC_QUEUE(txq_id), + /* Circular buffer (TFD queue in DRAM) physical base address */ + iwl4965_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), txq->q.dma_addr >> 8); - iwl_write_restricted( + + /* Enable DMA channel, using same id as for TFD queue */ + iwl4965_write_direct32( priv, IWL_FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | IWL_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -2715,13 +2801,14 @@ static inline u8 iwl4965_get_dma_hi_address(dma_addr_t addr) return sizeof(addr) > sizeof(u32) ? (addr >> 16) >> 16 : 0; } -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, +int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl4965_priv *priv, void *ptr, dma_addr_t addr, u16 len) { int index, is_odd; - struct iwl_tfd_frame *tfd = ptr; + struct iwl4965_tfd_frame *tfd = ptr; u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); + /* Each TFD can point to a maximum 20 Tx buffers */ if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) { IWL_ERROR("Error can not send more than %d chunks\n", MAX_NUM_OF_TBS); @@ -2748,7 +2835,7 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, return 0; } -void iwl_hw_card_show_info(struct iwl_priv *priv) +static void iwl4965_hw_card_show_info(struct iwl4965_priv *priv) { u16 hw_version = priv->eeprom.board_revision_4965; @@ -2763,32 +2850,41 @@ void iwl_hw_card_show_info(struct iwl_priv *priv) #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 -int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, - struct iwl_tx_queue *txq, u16 byte_cnt) +/** + * iwl4965_tx_queue_update_wr_ptr - Set up entry in Tx byte-count array + */ +int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, u16 byte_cnt) { int len; int txq_id = txq->q.id; - struct iwl_shared *shared_data = priv->hw_setting.shared_virt; + struct iwl4965_shared *shared_data = priv->hw_setting.shared_virt; if (txq->need_update == 0) return 0; len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE; + /* Set up byte count within first 256 entries */ IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. - tfd_offset[txq->q.first_empty], byte_cnt, len); + tfd_offset[txq->q.write_ptr], byte_cnt, len); - if (txq->q.first_empty < IWL4965_MAX_WIN_SIZE) + /* If within first 64 entries, duplicate at end */ + if (txq->q.write_ptr < IWL4965_MAX_WIN_SIZE) IWL_SET_BITS16(shared_data->queues_byte_cnt_tbls[txq_id]. - tfd_offset[IWL4965_QUEUE_SIZE + txq->q.first_empty], + tfd_offset[IWL4965_QUEUE_SIZE + txq->q.write_ptr], byte_cnt, len); return 0; } -/* Set up Rx receiver/antenna/chain usage in "staging" RXON image. - * This should not be used for scan command ... it puts data in wrong place. */ -void iwl4965_set_rxon_chain(struct iwl_priv *priv) +/** + * iwl4965_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 iwl4965_set_rxon_chain(struct iwl4965_priv *priv) { u8 is_single = is_single_stream(priv); u8 idle_state, rx_state; @@ -2819,19 +2915,19 @@ void iwl4965_set_rxon_chain(struct iwl_priv *priv) IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); } -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG /* get the traffic load value for tid */ -static u32 iwl4965_tl_get_load(struct iwl_priv *priv, u8 tid) +static u32 iwl4965_tl_get_load(struct iwl4965_priv *priv, u8 tid) { u32 load = 0; u32 current_time = jiffies_to_msecs(jiffies); u32 time_diff; s32 index; unsigned long flags; - struct iwl_traffic_load *tid_ptr = NULL; + struct iwl4965_traffic_load *tid_ptr = NULL; if (tid >= TID_MAX_LOAD_COUNT) return 0; @@ -2872,13 +2968,13 @@ static u32 iwl4965_tl_get_load(struct iwl_priv *priv, u8 tid) increment traffic load value for tid and also remove any old values if passed the certian time period */ -static void iwl4965_tl_add_packet(struct iwl_priv *priv, u8 tid) +static void iwl4965_tl_add_packet(struct iwl4965_priv *priv, u8 tid) { u32 current_time = jiffies_to_msecs(jiffies); u32 time_diff; s32 index; unsigned long flags; - struct iwl_traffic_load *tid_ptr = NULL; + struct iwl4965_traffic_load *tid_ptr = NULL; if (tid >= TID_MAX_LOAD_COUNT) return; @@ -2935,14 +3031,19 @@ enum HT_STATUS { BA_STATUS_ACTIVE, }; -static u8 iwl4964_tl_ba_avail(struct iwl_priv *priv) +/** + * iwl4964_tl_ba_avail - Find out if an unused aggregation queue is available + */ +static u8 iwl4964_tl_ba_avail(struct iwl4965_priv *priv) { int i; - struct iwl_lq_mngr *lq; + struct iwl4965_lq_mngr *lq; u8 count = 0; u16 msk; - lq = (struct iwl_lq_mngr *)&(priv->lq_mngr); + lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); + + /* Find out how many agg queues are in use */ for (i = 0; i < TID_MAX_LOAD_COUNT ; i++) { msk = 1 << i; if ((lq->agg_ctrl.granted_ba & msk) || @@ -2956,10 +3057,10 @@ static u8 iwl4964_tl_ba_avail(struct iwl_priv *priv) return 0; } -static void iwl4965_ba_status(struct iwl_priv *priv, +static void iwl4965_ba_status(struct iwl4965_priv *priv, u8 tid, enum HT_STATUS status); -static int iwl4965_perform_addba(struct iwl_priv *priv, u8 tid, u32 length, +static int iwl4965_perform_addba(struct iwl4965_priv *priv, u8 tid, u32 length, u32 ba_timeout) { int rc; @@ -2971,7 +3072,7 @@ static int iwl4965_perform_addba(struct iwl_priv *priv, u8 tid, u32 length, return rc; } -static int iwl4965_perform_delba(struct iwl_priv *priv, u8 tid) +static int iwl4965_perform_delba(struct iwl4965_priv *priv, u8 tid) { int rc; @@ -2982,8 +3083,8 @@ static int iwl4965_perform_delba(struct iwl_priv *priv, u8 tid) return rc; } -static void iwl4965_turn_on_agg_for_tid(struct iwl_priv *priv, - struct iwl_lq_mngr *lq, +static void iwl4965_turn_on_agg_for_tid(struct iwl4965_priv *priv, + struct iwl4965_lq_mngr *lq, u8 auto_agg, u8 tid) { u32 tid_msk = (1 << tid); @@ -3030,12 +3131,12 @@ static void iwl4965_turn_on_agg_for_tid(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); } -static void iwl4965_turn_on_agg(struct iwl_priv *priv, u8 tid) +static void iwl4965_turn_on_agg(struct iwl4965_priv *priv, u8 tid) { - struct iwl_lq_mngr *lq; + struct iwl4965_lq_mngr *lq; unsigned long flags; - lq = (struct iwl_lq_mngr *)&(priv->lq_mngr); + lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); if ((tid < TID_MAX_LOAD_COUNT)) iwl4965_turn_on_agg_for_tid(priv, lq, lq->agg_ctrl.auto_agg, @@ -3055,13 +3156,13 @@ static void iwl4965_turn_on_agg(struct iwl_priv *priv, u8 tid) } -void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid) +void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid) { u32 tid_msk; - struct iwl_lq_mngr *lq; + struct iwl4965_lq_mngr *lq; unsigned long flags; - lq = (struct iwl_lq_mngr *)&(priv->lq_mngr); + lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); if ((tid < TID_MAX_LOAD_COUNT)) { tid_msk = 1 << tid; @@ -3084,14 +3185,17 @@ void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid) } } -static void iwl4965_ba_status(struct iwl_priv *priv, +/** + * iwl4965_ba_status - Update driver's link quality mgr with tid's HT status + */ +static void iwl4965_ba_status(struct iwl4965_priv *priv, u8 tid, enum HT_STATUS status) { - struct iwl_lq_mngr *lq; + struct iwl4965_lq_mngr *lq; u32 tid_msk = (1 << tid); unsigned long flags; - lq = (struct iwl_lq_mngr *)&(priv->lq_mngr); + lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); if ((tid >= TID_MAX_LOAD_COUNT)) goto out; @@ -3124,14 +3228,14 @@ static void iwl4965_ba_status(struct iwl_priv *priv, static void iwl4965_bg_agg_work(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, agg_work); u32 tid; u32 retry_tid; u32 tid_msk; unsigned long flags; - struct iwl_lq_mngr *lq = (struct iwl_lq_mngr *)&(priv->lq_mngr); + struct iwl4965_lq_mngr *lq = (struct iwl4965_lq_mngr *)&(priv->lq_mngr); spin_lock_irqsave(&priv->lq_mngr.lock, flags); retry_tid = lq->agg_ctrl.tid_retry; @@ -3154,27 +3258,27 @@ static void iwl4965_bg_agg_work(struct work_struct *work) spin_unlock_irqrestore(&priv->lq_mngr.lock, flags); return; } -#endif /*CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ -int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, +int iwl4965_tx_cmd(struct iwl4965_priv *priv, struct iwl4965_cmd *out_cmd, u8 sta_id, dma_addr_t txcmd_phys, struct ieee80211_hdr *hdr, u8 hdr_len, struct ieee80211_tx_control *ctrl, void *sta_in) { - struct iwl_tx_cmd cmd; - struct iwl_tx_cmd *tx = (struct iwl_tx_cmd *)&out_cmd->cmd.payload[0]; + struct iwl4965_tx_cmd cmd; + struct iwl4965_tx_cmd *tx = (struct iwl4965_tx_cmd *)&out_cmd->cmd.payload[0]; dma_addr_t scratch_phys; u8 unicast = 0; u8 is_data = 1; u16 fc; u16 rate_flags; int rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1); -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG __le16 *qc; -#endif /*CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ unicast = !is_multicast_ether_addr(hdr->addr1); @@ -3182,8 +3286,8 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) is_data = 0; - memcpy(&cmd, &(out_cmd->cmd.tx), sizeof(struct iwl_tx_cmd)); - memset(tx, 0, sizeof(struct iwl_tx_cmd)); + memcpy(&cmd, &(out_cmd->cmd.tx), sizeof(struct iwl4965_tx_cmd)); + memset(tx, 0, sizeof(struct iwl4965_tx_cmd)); memcpy(tx->hdr, hdr, hdr_len); tx->len = cmd.len; @@ -3202,8 +3306,8 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, tx->rts_retry_limit = cmd.rts_retry_limit; tx->data_retry_limit = cmd.data_retry_limit; - scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); + scratch_phys = txcmd_phys + sizeof(struct iwl4965_cmd_header) + + offsetof(struct iwl4965_tx_cmd, scratch); tx->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx->dram_msb_ptr = iwl4965_get_dma_hi_address(scratch_phys); @@ -3229,14 +3333,14 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, tx->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; } - tx->rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[rate_index].plcp, + tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(iwl4965_rates[rate_index].plcp, rate_flags); if (ieee80211_is_back_request(fc)) tx->tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG qc = ieee80211_get_qos_ctrl(hdr); if (qc && (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) { @@ -3282,7 +3386,7 @@ static s32 sign_extend(u32 oper, int index) * * A return of <0 indicates bogus data in the statistics */ -int iwl4965_get_temperature(const struct iwl_priv *priv) +int iwl4965_get_temperature(const struct iwl4965_priv *priv) { s32 temperature; s32 vt; @@ -3305,11 +3409,12 @@ int iwl4965_get_temperature(const struct iwl_priv *priv) } /* - * Temperature is only 23 bits so sign extend out to 32 + * Temperature is only 23 bits, so sign extend out to 32. * * NOTE If we haven't received a statistics notification yet * with an updated temperature, use R4 provided to us in the - * ALIVE response. */ + * "initialize" ALIVE response. + */ if (!test_bit(STATUS_TEMPERATURE, &priv->status)) vt = sign_extend(R4, 23); else @@ -3349,7 +3454,7 @@ int iwl4965_get_temperature(const struct iwl_priv *priv) * Assumes caller will replace priv->last_temperature once calibration * executed. */ -static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) +static int iwl4965_is_temp_calib_needed(struct iwl4965_priv *priv) { int temp_diff; @@ -3382,7 +3487,7 @@ static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv) /* Calculate noise level, based on measurements during network silence just * before arriving beacon. This measurement can be done only if we know * exactly when to expect beacons, therefore only when we're associated. */ -static void iwl4965_rx_calc_noise(struct iwl_priv *priv) +static void iwl4965_rx_calc_noise(struct iwl4965_priv *priv) { struct statistics_rx_non_phy *rx_info = &(priv->statistics.rx.general); @@ -3419,9 +3524,9 @@ static void iwl4965_rx_calc_noise(struct iwl_priv *priv) priv->last_rx_noise); } -void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +void iwl4965_hw_rx_statistics(struct iwl4965_priv *priv, struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; int change; s32 temp; @@ -3448,7 +3553,7 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { iwl4965_rx_calc_noise(priv); -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY queue_work(priv->workqueue, &priv->sensitivity_work); #endif } @@ -3483,12 +3588,12 @@ void iwl_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) queue_work(priv->workqueue, &priv->txpower_work); } -static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, +static void iwl4965_handle_data_packet(struct iwl4965_priv *priv, int is_data, int include_phy, - struct iwl_rx_mem_buffer *rxb, + struct iwl4965_rx_mem_buffer *rxb, struct ieee80211_rx_status *stats) { - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; struct iwl4965_rx_phy_res *rx_start = (include_phy) ? (struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL; struct ieee80211_hdr *hdr; @@ -3524,8 +3629,8 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, rx_start->byte_count = amsdu->byte_count; rx_end = (__le32 *) (((u8 *) hdr) + len); } - if (len > 2342 || len < 16) { - IWL_DEBUG_DROP("byte count out of range [16,2342]" + if (len > priv->hw_setting.max_pkt_size || len < 16) { + IWL_WARNING("byte count out of range [16,4K]" " : %d\n", len); return; } @@ -3545,25 +3650,25 @@ static void iwl4965_handle_data_packet(struct iwl_priv *priv, int is_data, } if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) { - if (iwl_param_hwcrypto) - iwl_set_decrypted_flag(priv, rxb->skb, + if (iwl4965_param_hwcrypto) + iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); - iwl_handle_data_packet_monitor(priv, rxb, hdr, len, stats, 0); + iwl4965_handle_data_packet_monitor(priv, rxb, hdr, len, stats, 0); return; } stats->flag = 0; hdr = (struct ieee80211_hdr *)rxb->skb->data; - if (iwl_param_hwcrypto) - iwl_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); + if (iwl4965_param_hwcrypto) + iwl4965_set_decrypted_flag(priv, rxb->skb, ampdu_status, stats); ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats); priv->alloc_rxb_skb--; rxb->skb = NULL; #ifdef LED priv->led_packets += len; - iwl_setup_activity_timer(priv); + iwl4965_setup_activity_timer(priv); #endif } @@ -3601,7 +3706,7 @@ static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp) return (max_rssi - agc - IWL_RSSI_OFFSET); } -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT /* Parsed Information Elements */ struct ieee802_11_elems { @@ -3673,9 +3778,37 @@ static int parse_elems(u8 *start, size_t len, struct ieee802_11_elems *elems) return 0; } -#endif /* CONFIG_IWLWIFI_HT */ -static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) +void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, int mode) +{ + ht_info->cap = 0; + memset(ht_info->supp_mcs_set, 0, 16); + + ht_info->ht_supported = 1; + + if (mode == MODE_IEEE80211A) { + ht_info->cap |= (u16)IEEE80211_HT_CAP_SUP_WIDTH; + ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_40; + ht_info->supp_mcs_set[4] = 0x01; + } + ht_info->cap |= (u16)IEEE80211_HT_CAP_GRN_FLD; + ht_info->cap |= (u16)IEEE80211_HT_CAP_SGI_20; + ht_info->cap |= (u16)(IEEE80211_HT_CAP_MIMO_PS & + (IWL_MIMO_PS_NONE << 2)); + if (iwl4965_param_amsdu_size_8K) { + printk(KERN_DEBUG "iwl4965 in A-MSDU 8K support mode\n"); + ht_info->cap |= (u16)IEEE80211_HT_CAP_MAX_AMSDU; + } + + ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; + ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; + + ht_info->supp_mcs_set[0] = 0xFF; + ht_info->supp_mcs_set[1] = 0xFF; +} +#endif /* CONFIG_IWL4965_HT */ + +static void iwl4965_sta_modify_ps_wake(struct iwl4965_priv *priv, int sta_id) { unsigned long flags; @@ -3686,13 +3819,13 @@ static void iwl4965_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } -static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) +static void iwl4965_update_ps_mode(struct iwl4965_priv *priv, u16 ps_bit, u8 *addr) { /* FIXME: need locking over ps_status ??? */ - u8 sta_id = iwl_hw_find_station(priv, addr); + u8 sta_id = iwl4965_hw_find_station(priv, addr); if (sta_id != IWL_INVALID_STATION) { u8 sta_awake = priv->stations[sta_id]. @@ -3707,12 +3840,14 @@ static void iwl4965_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) } } +#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) + /* Called for REPLY_4965_RX (legacy ABG frames), or * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ -static void iwl4965_rx_reply_rx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_rx(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; /* Use phy data (Rx signal strength, etc.) contained within * this rx packet for legacy frames, * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ @@ -3731,11 +3866,11 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? MODE_IEEE80211G : MODE_IEEE80211A, .antenna = 0, - .rate = iwl_hw_get_rate(rx_start->rate_n_flags), + .rate = iwl4965_hw_get_rate(rx_start->rate_n_flags), .flag = 0, -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT_AGG .ordered = 0 -#endif /* CONFIG_IWLWIFI_HT_AGG */ +#endif /* CONFIG_IWL4965_HT_AGG */ }; u8 network_packet; @@ -3794,32 +3929,32 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, * which are gathered only when associated, and indicate noise * only for the associated network channel ... * Ignore these noise values while scanning (other channels) */ - if (iwl_is_associated(priv) && + if (iwl4965_is_associated(priv) && !test_bit(STATUS_SCANNING, &priv->status)) { stats.noise = priv->last_rx_noise; - stats.signal = iwl_calc_sig_qual(stats.ssi, stats.noise); + stats.signal = iwl4965_calc_sig_qual(stats.ssi, stats.noise); } else { stats.noise = IWL_NOISE_MEAS_NOT_AVAILABLE; - stats.signal = iwl_calc_sig_qual(stats.ssi, 0); + stats.signal = iwl4965_calc_sig_qual(stats.ssi, 0); } /* Reset beacon noise level if not associated. */ - if (!iwl_is_associated(priv)) + if (!iwl4965_is_associated(priv)) priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; -#ifdef CONFIG_IWLWIFI_DEBUG - /* TODO: Parts of iwl_report_frame are broken for 4965 */ - if (iwl_debug_level & (IWL_DL_RX)) +#ifdef CONFIG_IWL4965_DEBUG + /* TODO: Parts of iwl4965_report_frame are broken for 4965 */ + if (iwl4965_debug_level & (IWL_DL_RX)) /* Set "1" to report good data frames in groups of 100 */ - iwl_report_frame(priv, pkt, header, 1); + iwl4965_report_frame(priv, pkt, header, 1); - if (iwl_debug_level & (IWL_DL_RX | IWL_DL_STATS)) + if (iwl4965_debug_level & (IWL_DL_RX | IWL_DL_STATS)) IWL_DEBUG_RX("Rssi %d, noise %d, qual %d, TSF %lu\n", stats.ssi, stats.noise, stats.signal, (long unsigned int)le64_to_cpu(rx_start->timestamp)); #endif - network_packet = iwl_is_network_packet(priv, header); + network_packet = iwl4965_is_network_packet(priv, header); if (network_packet) { priv->last_rx_rssi = stats.ssi; priv->last_beacon_time = priv->ucode_beacon_time; @@ -3871,19 +4006,25 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, case IEEE80211_STYPE_ASSOC_RESP: case IEEE80211_STYPE_REASSOC_RESP: if (network_packet) { -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT u8 *pos = NULL; struct ieee802_11_elems elems; -#endif /*CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT */ struct ieee80211_mgmt *mgnt = (struct ieee80211_mgmt *)header; + /* We have just associated, give some + * time for the 4-way handshake if + * any. Don't start scan too early. */ + priv->next_scan_jiffies = jiffies + + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; + priv->assoc_id = (~((1 << 15) | (1 << 14)) & le16_to_cpu(mgnt->u.assoc_resp.aid)); priv->assoc_capability = le16_to_cpu( mgnt->u.assoc_resp.capab_info); -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT pos = mgnt->u.assoc_resp.variable; if (!parse_elems(pos, len - (pos - (u8 *) mgnt), @@ -3892,7 +4033,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, elems.ht_cap_param) break; } -#endif /*CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT */ /* assoc_id is 0 no association */ if (!priv->assoc_id) break; @@ -3907,7 +4048,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, case IEEE80211_STYPE_PROBE_REQ: if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && - !iwl_is_associated(priv)) { + !iwl4965_is_associated(priv)) { DECLARE_MAC_BUF(mac1); DECLARE_MAC_BUF(mac2); DECLARE_MAC_BUF(mac3); @@ -3924,7 +4065,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, break; case IEEE80211_FTYPE_CTL: -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT_AGG switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_BACK_REQ: IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); @@ -3953,7 +4094,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, print_mac(mac1, header->addr1), print_mac(mac2, header->addr2), print_mac(mac3, header->addr3)); - else if (unlikely(is_duplicate_packet(priv, header))) + else if (unlikely(iwl4965_is_duplicate_packet(priv, header))) IWL_DEBUG_DROP("Dropping (dup): %s, %s, %s\n", print_mac(mac1, header->addr1), print_mac(mac2, header->addr2), @@ -3971,22 +4112,22 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv, /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD). * This will be used later in iwl4965_rx_reply_rx() for REPLY_RX_MPDU_CMD. */ -static void iwl4965_rx_reply_rx_phy(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_rx_phy(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; priv->last_phy_res[0] = 1; memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]), sizeof(struct iwl4965_rx_phy_res)); } -static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_missed_beacon_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_SENSITIVITY - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_missed_beacon_notif *missed_beacon; +#ifdef CONFIG_IWL4965_SENSITIVITY + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_missed_beacon_notif *missed_beacon; missed_beacon = &pkt->u.missed_beacon; if (le32_to_cpu(missed_beacon->consequtive_missed_beacons) > 5) { @@ -3999,13 +4140,18 @@ static void iwl4965_rx_missed_beacon_notif(struct iwl_priv *priv, if (unlikely(!test_bit(STATUS_SCANNING, &priv->status))) queue_work(priv->workqueue, &priv->sensitivity_work); } -#endif /*CONFIG_IWLWIFI_SENSITIVITY*/ +#endif /*CONFIG_IWL4965_SENSITIVITY*/ } -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG -static void iwl4965_set_tx_status(struct iwl_priv *priv, int txq_id, int idx, +/** + * iwl4965_set_tx_status - Update driver's record of one Tx frame's status + * + * This will get sent to mac80211. + */ +static void iwl4965_set_tx_status(struct iwl4965_priv *priv, int txq_id, int idx, u32 status, u32 retry_count, u32 rate) { struct ieee80211_tx_status *tx_status = @@ -4017,24 +4163,34 @@ static void iwl4965_set_tx_status(struct iwl_priv *priv, int txq_id, int idx, } -static void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, +/** + * iwl4965_sta_modify_enable_tid_tx - Enable Tx for this TID in station table + */ +static void iwl4965_sta_modify_enable_tid_tx(struct iwl4965_priv *priv, int sta_id, int tid) { unsigned long flags; + /* 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; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } -static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_ht_agg *agg, - struct iwl_compressed_ba_resp* +/** + * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack + * + * Go through block-ack's bitmap of ACK'd frames, update driver's record of + * ACK vs. not. This gets sent to mac80211, then to rate scaling algo. + */ +static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, + struct iwl4965_ht_agg *agg, + struct iwl4965_compressed_ba_resp* ba_resp) { @@ -4048,13 +4204,17 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, IWL_ERROR("Received BA when not expected\n"); return -EINVAL; } + + /* Mark that the expected block-ack response arrived */ agg->wait_for_ba = 0; IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->ba_seq_ctl); + + /* Calculate shift to align block-ack bits with our Tx window bits */ sh = agg->start_idx - SEQ_TO_INDEX(ba_seq_ctl>>4); - if (sh < 0) /* tbw something is wrong with indeces */ + if (sh < 0) /* tbw something is wrong with indices */ sh += 0x100; - /* don't use 64 bits for now */ + /* don't use 64-bit values for now */ bitmap0 = resp_bitmap0 >> sh; bitmap1 = resp_bitmap1 >> sh; bitmap0 |= (resp_bitmap1 & ((1<bitmap0; bitmap1 &= agg->bitmap1; + /* For each frame attempted in aggregation, + * update driver's record of tx frame's status. */ for (i = 0; i < agg->frame_count ; i++) { int idx = (agg->start_idx + i) & 0xff; ack = bitmap0 & (1 << i); @@ -4084,20 +4246,36 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, return 0; } -static inline int iwl_queue_dec_wrap(int index, int n_bd) +/** + * iwl4965_queue_dec_wrap - Decrement queue index, wrap back to end if needed + * @index -- current index + * @n_bd -- total number of entries in queue (s/b power of 2) + */ +static inline int iwl4965_queue_dec_wrap(int index, int n_bd) { return (index == 0) ? n_bd - 1 : index - 1; } -static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +/** + * iwl4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA + * + * Handles block-acknowledge notification from device, which reports success + * of frames sent via aggregation. + */ +static void iwl4965_rx_reply_compressed_ba(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; int index; - struct iwl_tx_queue *txq = NULL; - struct iwl_ht_agg *agg; + struct iwl4965_tx_queue *txq = NULL; + struct iwl4965_ht_agg *agg; + + /* "flow" corresponds to Tx queue */ u16 ba_resp_scd_flow = le16_to_cpu(ba_resp->scd_flow); + + /* "ssn" is start of block-ack Tx window, corresponds to index + * (in Tx queue's circular buffer) of first TFD/frame in window */ u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); if (ba_resp_scd_flow >= ARRAY_SIZE(priv->txq)) { @@ -4107,9 +4285,11 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, txq = &priv->txq[ba_resp_scd_flow]; agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; - index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); - /* TODO: Need to get this copy more sefely - now good for debug */ + /* Find index just before block-ack window */ + index = iwl4965_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); + + /* TODO: Need to get this copy more safely - now good for debug */ /* { DECLARE_MAC_BUF(mac); @@ -4132,23 +4312,36 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, agg->bitmap0); } */ + + /* Update driver's record of ACK vs. not for each frame in window */ iwl4965_tx_status_reply_compressed_ba(priv, agg, ba_resp); - /* releases all the TFDs until the SSN */ - if (txq->q.last_used != (ba_resp_scd_ssn & 0xff)) - iwl_tx_queue_reclaim(priv, ba_resp_scd_flow, index); + + /* Release all TFDs before the SSN, i.e. all TFDs in front of + * block-ack window (we assume that they've been successfully + * transmitted ... if not, it's too late anyway). */ + if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) + iwl4965_tx_queue_reclaim(priv, ba_resp_scd_flow, index); } -static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id) +/** + * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration + */ +static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, u16 txq_id) { - iwl_write_restricted_reg(priv, - SCD_QUEUE_STATUS_BITS(txq_id), + /* Simply stop the queue, but don't change any configuration; + * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ + iwl4965_write_prph(priv, + KDR_SCD_QUEUE_STATUS_BITS(txq_id), (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); } -static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, +/** + * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue + */ +static int iwl4965_tx_queue_set_q2ratid(struct iwl4965_priv *priv, u16 ra_tid, u16 txq_id) { u32 tbl_dw_addr; @@ -4160,22 +4353,25 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, tbl_dw_addr = priv->scd_base_addr + SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_read_restricted_mem(priv, tbl_dw_addr); + tbl_dw = iwl4965_read_targ_mem(priv, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_write_restricted_mem(priv, tbl_dw_addr, tbl_dw); + iwl4965_write_targ_mem(priv, tbl_dw_addr, tbl_dw); return 0; } /** - * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID + * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue + * + * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID, + * i.e. it must be one of the higher queues used for aggregation */ -static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id, +static int iwl4965_tx_queue_agg_enable(struct iwl4965_priv *priv, int txq_id, int tx_fifo, int sta_id, int tid, u16 ssn_idx) { @@ -4189,43 +4385,48 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id, ra_tid = BUILD_RAxTID(sta_id, tid); - iwl_sta_modify_enable_tid_tx(priv, sta_id, tid); + /* Modify device's station table to Tx this TID */ + iwl4965_sta_modify_enable_tid_tx(priv, sta_id, tid); spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } + /* Stop this Tx queue before configuring it */ iwl4965_tx_queue_stop_scheduler(priv, txq_id); + /* Map receiver-address / traffic-ID to this queue */ iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id); + /* Set this queue as a chain-building queue */ + iwl4965_set_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1<txq[txq_id].q.last_used = (ssn_idx & 0xff); - priv->txq[txq_id].q.first_empty = (ssn_idx & 0xff); - - /* supposes that ssn_idx is valid (!= 0xFFF) */ + /* Place first TFD at index corresponding to start sequence number. + * Assumes that ssn_idx is valid (!= 0xFFF) */ + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - iwl_write_restricted_mem(priv, + /* Set up Tx window size and frame limit for this queue */ + iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id), (SCD_WIN_SIZE << SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) & SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK); - iwl_write_restricted_mem(priv, priv->scd_base_addr + + iwl4965_write_targ_mem(priv, priv->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), (SCD_FRAME_LIMIT << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK); - iwl_set_bits_restricted_reg(priv, SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl4965_set_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); + /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; @@ -4234,7 +4435,7 @@ static int iwl4965_tx_queue_agg_enable(struct iwl_priv *priv, int txq_id, /** * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID */ -static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id, +static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { unsigned long flags; @@ -4247,7 +4448,7 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id, } spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; @@ -4255,56 +4456,50 @@ static int iwl4965_tx_queue_agg_disable(struct iwl_priv *priv, u16 txq_id, iwl4965_tx_queue_stop_scheduler(priv, txq_id); - iwl_clear_bits_restricted_reg(priv, SCD_QUEUECHAIN_SEL, (1 << txq_id)); + iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); - priv->txq[txq_id].q.last_used = (ssn_idx & 0xff); - priv->txq[txq_id].q.first_empty = (ssn_idx & 0xff); + priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); /* supposes that ssn_idx is valid (!= 0xFFF) */ iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx); - iwl_clear_bits_restricted_reg(priv, SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl4965_clear_bits_prph(priv, KDR_SCD_INTERRUPT_MASK, (1 << txq_id)); iwl4965_txq_ctx_deactivate(priv, txq_id); iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); return 0; } -#endif/* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ -/* - * RATE SCALE CODE - */ -int iwl4965_init_hw_rates(struct iwl_priv *priv, struct ieee80211_rate *rates) -{ - return 0; -} - +#endif/* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ /** * iwl4965_add_station - Initialize a station's hardware rate table * - * The uCode contains a table of fallback rates and retries per rate + * The uCode's station table contains a table of fallback rates * for automatic fallback during transmission. * - * NOTE: This initializes the table for a single retry per data rate - * which is not optimal. Setting up an intelligent retry per rate - * requires feedback from transmission, which isn't exposed through - * rc80211_simple which is what this driver is currently using. + * NOTE: This sets up a default set of values. These will be replaced later + * if the driver's iwl-4965-rs rate scaling algorithm is used, instead of + * rc80211_simple. * + * NOTE: Run REPLY_ADD_STA command to set up station table entry, before + * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, + * which requires station table entry to exist). */ -void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) +void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) { int i, r; - struct iwl_link_quality_cmd link_cmd = { + struct iwl4965_link_quality_cmd link_cmd = { .reserved1 = 0, }; u16 rate_flags; - /* Set up the rate scaling to start at 54M and fallback - * all the way to 1M in IEEE order and then spin on IEEE */ + /* 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 (is_ap) r = IWL_RATE_54M_INDEX; else if (priv->phymode == MODE_IEEE80211A) @@ -4317,11 +4512,13 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) rate_flags |= RATE_MCS_CCK_MSK; + /* Use Tx antenna B only */ rate_flags |= RATE_MCS_ANT_B_MSK; rate_flags &= ~RATE_MCS_ANT_A_MSK; + 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); + iwl4965_hw_set_rate_n_flags(iwl4965_rates[r].plcp, rate_flags); + r = iwl4965_get_prev_ieee_rate(r); } link_cmd.general_params.single_stream_ant_msk = 2; @@ -4332,18 +4529,18 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) /* Update the rate scaling for control frame Tx to AP */ link_cmd.sta_id = is_ap ? IWL_AP_ID : IWL4965_BROADCAST_ID; - iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd), + iwl4965_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd), &link_cmd); } -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT -static u8 iwl_is_channel_extension(struct iwl_priv *priv, int phymode, +static u8 iwl4965_is_channel_extension(struct iwl4965_priv *priv, int phymode, u16 channel, u8 extension_chan_offset) { - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, phymode, channel); + ch_info = iwl4965_get_channel_info(priv, phymode, channel); if (!is_channel_valid(ch_info)) return 0; @@ -4357,36 +4554,37 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, int phymode, return 0; } -static u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, - const struct sta_ht_info *ht_info) +static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv, + struct ieee80211_ht_info *sta_ht_inf) { + struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config; - if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ) + if ((!iwl_ht_conf->is_ht) || + (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || + (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO)) return 0; - if (ht_info->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) - return 0; - - if (ht_info->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_AUTO) - return 0; + if (sta_ht_inf) { + if ((!sta_ht_inf->ht_supported) || + (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)) + return 0; + } - /* no fat tx allowed on 2.4GHZ */ - if (priv->phymode != MODE_IEEE80211A) - return 0; - return (iwl_is_channel_extension(priv, priv->phymode, - ht_info->control_channel, - ht_info->extension_chan_offset)); + return (iwl4965_is_channel_extension(priv, priv->phymode, + iwl_ht_conf->control_channel, + iwl_ht_conf->extension_chan_offset)); } -void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info) +void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, struct iwl_ht_info *ht_info) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; u32 val; if (!ht_info->is_ht) return; - if (iwl_is_fat_tx_allowed(priv, ht_info)) + /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ + if (iwl4965_is_fat_tx_allowed(priv, NULL)) rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK; else rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | @@ -4400,7 +4598,7 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info) return; } - /* Note: control channel is oposit to extension channel */ + /* Note: control channel is opposite of extension channel */ switch (ht_info->extension_chan_offset) { case IWL_EXT_CHANNEL_OFFSET_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); @@ -4416,66 +4614,58 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct sta_ht_info *ht_info) break; } - val = ht_info->operating_mode; + val = ht_info->ht_protection; rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS); - priv->active_rate_ht[0] = ht_info->supp_rates[0]; - priv->active_rate_ht[1] = ht_info->supp_rates[1]; iwl4965_set_rxon_chain(priv); IWL_DEBUG_ASSOC("supported HT rate 0x%X %X " "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x " "control chan %d\n", - priv->active_rate_ht[0], priv->active_rate_ht[1], - le32_to_cpu(rxon->flags), ht_info->operating_mode, + ht_info->supp_mcs_set[0], ht_info->supp_mcs_set[1], + le32_to_cpu(rxon->flags), ht_info->ht_protection, ht_info->extension_chan_offset, ht_info->control_channel); return; } -void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index) +void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, + struct ieee80211_ht_info *sta_ht_inf) { __le32 sta_flags; - struct sta_ht_info *ht_info = &priv->current_assoc_ht; - priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ; - if (!ht_info->is_ht) + if (!sta_ht_inf || !sta_ht_inf->ht_supported) goto done; sta_flags = priv->stations[index].sta.station_flags; - if (ht_info->tx_mimo_ps_mode == IWL_MIMO_PS_DYNAMIC) + if (((sta_ht_inf->cap & IEEE80211_HT_CAP_MIMO_PS >> 2)) + == IWL_MIMO_PS_DYNAMIC) sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK; else sta_flags &= ~STA_FLG_RTS_MIMO_PROT_MSK; sta_flags |= cpu_to_le32( - (u32)ht_info->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); + (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS); sta_flags |= cpu_to_le32( - (u32)ht_info->mpdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - - sta_flags &= (~STA_FLG_FAT_EN_MSK); - ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_20MHZ; - ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_20MHZ; + (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (iwl_is_fat_tx_allowed(priv, ht_info)) { + if (iwl4965_is_fat_tx_allowed(priv, sta_ht_inf)) sta_flags |= STA_FLG_FAT_EN_MSK; - ht_info->chan_width_cap = IWL_CHANNEL_WIDTH_40MHZ; - if (ht_info->supported_chan_width == IWL_CHANNEL_WIDTH_40MHZ) - ht_info->tx_chan_width = IWL_CHANNEL_WIDTH_40MHZ; - } - priv->current_channel_width = ht_info->tx_chan_width; + else + sta_flags &= (~STA_FLG_FAT_EN_MSK); + priv->stations[index].sta.station_flags = sta_flags; done: return; } -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT_AGG -static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv, +static void iwl4965_sta_modify_add_ba_tid(struct iwl4965_priv *priv, int sta_id, int tid, u16 ssn) { unsigned long flags; @@ -4488,10 +4678,10 @@ static void iwl4965_sta_modify_add_ba_tid(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } -static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv, +static void iwl4965_sta_modify_del_ba_tid(struct iwl4965_priv *priv, int sta_id, int tid) { unsigned long flags; @@ -4503,7 +4693,7 @@ static void iwl4965_sta_modify_del_ba_tid(struct iwl_priv *priv, priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, CMD_ASYNC); } static const u16 default_tid_to_tx_fifo[] = { @@ -4526,7 +4716,13 @@ static const u16 default_tid_to_tx_fifo[] = { IWL_TX_FIFO_AC3 }; -static int iwl_txq_ctx_activate_free(struct iwl_priv *priv) +/* + * Find first available (lowest unused) Tx Queue, mark it "active". + * Called only when finding queue for aggregation. + * Should never return anything < 7, because they should already + * be in use as EDCA AC (0-3), Command (4), HCCA (5, 6). + */ +static int iwl4965_txq_ctx_activate_free(struct iwl4965_priv *priv) { int txq_id; @@ -4536,55 +4732,65 @@ static int iwl_txq_ctx_activate_free(struct iwl_priv *priv) return -1; } -int iwl_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, +int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, u16 *start_seq_num) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; int sta_id; int tx_fifo; int txq_id; int ssn = -1; unsigned long flags; - struct iwl_tid_data *tid_data; + struct iwl4965_tid_data *tid_data; DECLARE_MAC_BUF(mac); + /* Determine Tx DMA/FIFO channel for this Traffic ID */ if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) tx_fifo = default_tid_to_tx_fifo[tid]; else return -EINVAL; - IWL_WARNING("iwl-AGG iwl_mac_ht_tx_agg_start on da=%s" + IWL_WARNING("iwl-AGG iwl4965_mac_ht_tx_agg_start on da=%s" " tid=%d\n", print_mac(mac, da), tid); - sta_id = iwl_hw_find_station(priv, da); + /* Get index into station table */ + sta_id = iwl4965_hw_find_station(priv, da); if (sta_id == IWL_INVALID_STATION) return -ENXIO; - txq_id = iwl_txq_ctx_activate_free(priv); + /* Find available Tx queue for aggregation */ + txq_id = iwl4965_txq_ctx_activate_free(priv); if (txq_id == -1) return -ENXIO; spin_lock_irqsave(&priv->sta_lock, flags); tid_data = &priv->stations[sta_id].tid[tid]; + + /* Get starting sequence number for 1st frame in block ack window. + * We'll use least signif byte as 1st frame's index into Tx queue. */ ssn = SEQ_TO_SN(tid_data->seq_number); tid_data->agg.txq_id = txq_id; spin_unlock_irqrestore(&priv->sta_lock, flags); *start_seq_num = ssn; + + /* Update driver's link quality manager */ iwl4965_ba_status(priv, tid, BA_STATUS_ACTIVE); + + /* Set up and enable aggregation for selected Tx queue and FIFO */ return iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, ssn); } -int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, +int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, int generator) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; int tx_fifo_id, txq_id, sta_id, ssn = -1; - struct iwl_tid_data *tid_data; + struct iwl4965_tid_data *tid_data; int rc; DECLARE_MAC_BUF(mac); @@ -4598,7 +4804,7 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, else return -EINVAL; - sta_id = iwl_hw_find_station(priv, da); + sta_id = iwl4965_hw_find_station(priv, da); if (sta_id == IWL_INVALID_STATION) return -ENXIO; @@ -4613,45 +4819,45 @@ int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, return rc; iwl4965_ba_status(priv, tid, BA_STATUS_INITIATOR_DELBA); - IWL_DEBUG_INFO("iwl_mac_ht_tx_agg_stop on da=%s tid=%d\n", + IWL_DEBUG_INFO("iwl4965_mac_ht_tx_agg_stop on da=%s tid=%d\n", print_mac(mac, da), tid); return 0; } -int iwl_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da, +int iwl4965_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, u16 start_seq_num) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; int sta_id; DECLARE_MAC_BUF(mac); - IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_start on da=%s" + IWL_WARNING("iwl-AGG iwl4965_mac_ht_rx_agg_start on da=%s" " tid=%d\n", print_mac(mac, da), tid); - sta_id = iwl_hw_find_station(priv, da); + sta_id = iwl4965_hw_find_station(priv, da); iwl4965_sta_modify_add_ba_tid(priv, sta_id, tid, start_seq_num); return 0; } -int iwl_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da, +int iwl4965_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, int generator) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; int sta_id; DECLARE_MAC_BUF(mac); - IWL_WARNING("iwl-AGG iwl_mac_ht_rx_agg_stop on da=%s tid=%d\n", + IWL_WARNING("iwl-AGG iwl4965_mac_ht_rx_agg_stop on da=%s tid=%d\n", print_mac(mac, da), tid); - sta_id = iwl_hw_find_station(priv, da); + sta_id = iwl4965_hw_find_station(priv, da); iwl4965_sta_modify_del_ba_tid(priv, sta_id, tid); return 0; } -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ /* Set up 4965-specific Rx frame reply handlers */ -void iwl_hw_rx_handler_setup(struct iwl_priv *priv) +void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv) { /* Legacy Rx frames */ priv->rx_handlers[REPLY_4965_RX] = iwl4965_rx_reply_rx; @@ -4663,57 +4869,66 @@ void iwl_hw_rx_handler_setup(struct iwl_priv *priv) priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] = iwl4965_rx_missed_beacon_notif; -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; -#endif /* CONFIG_IWLWIFI_AGG */ -#endif /* CONFIG_IWLWIFI */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ } -void iwl_hw_setup_deferred_work(struct iwl_priv *priv) +void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv) { INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); INIT_WORK(&priv->statistics_work, iwl4965_bg_statistics_work); -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); #endif -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG INIT_WORK(&priv->agg_work, iwl4965_bg_agg_work); -#endif /* CONFIG_IWLWIFI_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ init_timer(&priv->statistics_periodic); priv->statistics_periodic.data = (unsigned long)priv; priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; } -void iwl_hw_cancel_deferred_work(struct iwl_priv *priv) +void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv) { del_timer_sync(&priv->statistics_periodic); cancel_delayed_work(&priv->init_alive_start); } -struct pci_device_id iwl_hw_card_ids[] = { - {0x8086, 0x4229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0x8086, 0x4230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, +struct pci_device_id iwl4965_hw_card_ids[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4229)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4230)}, {0} }; -int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv) +/* + * 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 iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv) { u16 count; int rc; for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + /* Request semaphore */ + iwl4965_set_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - rc = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + + /* See if we got it */ + rc = iwl4965_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 (rc >= 0) { - IWL_DEBUG_IO("Aqcuired semaphore after %d tries.\n", + IWL_DEBUG_IO("Acquired semaphore after %d tries.\n", count+1); return rc; } @@ -4722,11 +4937,11 @@ int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv) return rc; } -inline void iwl_eeprom_release_semaphore(struct iwl_priv *priv) +inline void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv) { - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + iwl4965_clear_bit(priv, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); } -MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +MODULE_DEVICE_TABLE(pci, iwl4965_hw_card_ids); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index 4c70081..5a410e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h @@ -23,64 +23,802 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 * *****************************************************************************/ +/* + * Please use this file (iwl-4965.h) for driver implementation definitions. + * Please use iwl-4965-commands.h for uCode API definitions. + * Please use iwl-4965-hw.h for hardware-related definitions. + */ + #ifndef __iwl_4965_h__ #define __iwl_4965_h__ -struct iwl_priv; -struct sta_ht_info; +#include /* for struct pci_device_id */ +#include +#include + +/* Hardware specific file defines the PCI IDs table for that hardware module */ +extern struct pci_device_id iwl4965_hw_card_ids[]; + +#define DRV_NAME "iwl4965" +#include "iwl-4965-hw.h" +#include "iwl-prph.h" +#include "iwl-4965-debug.h" + +/* Default noise level to report when noise measurement is not available. + * This may be because we're: + * 1) Not associated (4965, no beacon statistics being sent to driver) + * 2) Scanning (noise measurement does not apply to associated channel) + * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) + * Use default noise value of -127 ... this is below the range of measurable + * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. + * Also, -127 works better than 0 when averaging frames with/without + * noise info (e.g. averaging might be done in app); measured dBm values are + * always negative ... using a negative value as the default keeps all + * averages within an s8's (used in some apps) range of negative values. */ +#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) + +/* Module parameters accessible from iwl-*.c */ +extern int iwl4965_param_hwcrypto; +extern int iwl4965_param_queues_num; +extern int iwl4965_param_amsdu_size_8K; + +enum iwl4965_antenna { + IWL_ANTENNA_DIVERSITY, + IWL_ANTENNA_MAIN, + IWL_ANTENNA_AUX +}; + +/* + * RTS threshold here is total size [2347] minus 4 FCS bytes + * Per spec: + * a value of 0 means RTS on all data/management packets + * a value > max MSDU size means no RTS + * else RTS for data/management frames where MPDU is larger + * than RTS value. + */ +#define DEFAULT_RTS_THRESHOLD 2347U +#define MIN_RTS_THRESHOLD 0U +#define MAX_RTS_THRESHOLD 2347U +#define MAX_MSDU_SIZE 2304U +#define MAX_MPDU_SIZE 2346U +#define DEFAULT_BEACON_INTERVAL 100U +#define DEFAULT_SHORT_RETRY_LIMIT 7U +#define DEFAULT_LONG_RETRY_LIMIT 4U + +struct iwl4965_rx_mem_buffer { + dma_addr_t dma_addr; + struct sk_buff *skb; + struct list_head list; +}; + +struct iwl4965_rt_rx_hdr { + struct ieee80211_radiotap_header rt_hdr; + __le64 rt_tsf; /* TSF */ + u8 rt_flags; /* radiotap packet flags */ + u8 rt_rate; /* rate in 500kb/s */ + __le16 rt_channelMHz; /* channel in MHz */ + __le16 rt_chbitmask; /* channel bitfield */ + s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ + s8 rt_dbmnoise; + u8 rt_antenna; /* antenna number */ + u8 payload[0]; /* payload... */ +} __attribute__ ((packed)); + +struct iwl4965_rt_tx_hdr { + struct ieee80211_radiotap_header rt_hdr; + u8 rt_rate; /* rate in 500kb/s */ + __le16 rt_channel; /* channel in mHz */ + __le16 rt_chbitmask; /* channel bitfield */ + s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ + u8 rt_antenna; /* antenna number */ + u8 payload[0]; /* payload... */ +} __attribute__ ((packed)); + +/* + * Generic queue structure + * + * Contains common data for Rx and Tx queues + */ +struct iwl4965_queue { + int n_bd; /* number of BDs in this queue */ + int write_ptr; /* 1-st empty entry (index) host_w*/ + int read_ptr; /* last used entry (index) host_r*/ + dma_addr_t dma_addr; /* physical addr for BD's */ + int n_window; /* safe queue window */ + u32 id; + int low_mark; /* low watermark, resume queue if free + * space more than this */ + int high_mark; /* high watermark, stop queue if free + * space less than this */ +} __attribute__ ((packed)); + +#define MAX_NUM_OF_TBS (20) + +/* One for each TFD */ +struct iwl4965_tx_info { + struct ieee80211_tx_status status; + struct sk_buff *skb[MAX_NUM_OF_TBS]; +}; + +/** + * struct iwl4965_tx_queue - Tx Queue for DMA + * @q: generic Rx/Tx queue descriptor + * @bd: base of circular buffer of TFDs + * @cmd: array of command/Tx buffers + * @dma_addr_cmd: physical address of cmd/tx buffer array + * @txb: array of per-TFD driver data + * @need_update: indicates need to update read/write index + * @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled + * + * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame + * descriptors) and required locking structures. + */ +struct iwl4965_tx_queue { + struct iwl4965_queue q; + struct iwl4965_tfd_frame *bd; + struct iwl4965_cmd *cmd; + dma_addr_t dma_addr_cmd; + struct iwl4965_tx_info *txb; + int need_update; + int sched_retry; + int active; +}; + +#define IWL_NUM_SCAN_RATES (2) + +struct iwl4965_channel_tgd_info { + u8 type; + s8 max_power; +}; + +struct iwl4965_channel_tgh_info { + s64 last_radar_time; +}; + +/* current Tx power values to use, one for each rate for each channel. + * requested power is limited by: + * -- regulatory EEPROM limits for this channel + * -- hardware capabilities (clip-powers) + * -- spectrum management + * -- user preference (e.g. iwconfig) + * when requested power is set, base power index must also be set. */ +struct iwl4965_channel_power_info { + struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 base_power_index; /* gain index for power at factory temp. */ + s8 requested_power; /* power (dBm) requested for this chnl/rate */ +}; + +/* current scan Tx power values to use, one for each scan rate for each + * channel. */ +struct iwl4965_scan_power_info { + struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ +}; + +/* For fat_extension_channel */ +enum { + HT_IE_EXT_CHANNEL_NONE = 0, + HT_IE_EXT_CHANNEL_ABOVE, + HT_IE_EXT_CHANNEL_INVALID, + HT_IE_EXT_CHANNEL_BELOW, + HT_IE_EXT_CHANNEL_MAX +}; + +/* + * One for each channel, holds all channel setup data + * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant + * with one another! + */ +#define IWL4965_MAX_RATE (33) + +struct iwl4965_channel_info { + struct iwl4965_channel_tgd_info tgd; + struct iwl4965_channel_tgh_info tgh; + struct iwl4965_eeprom_channel eeprom; /* EEPROM regulatory limit */ + struct iwl4965_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for + * FAT channel */ + + u8 channel; /* channel number */ + u8 flags; /* flags copied from EEPROM */ + s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ + s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) limit */ + s8 min_power; /* always 0 */ + s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ + + u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ + u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ + u8 phymode; /* MODE_IEEE80211{A,B,G} */ + + /* Radio/DSP gain settings for each "normal" data Tx rate. + * These include, in addition to RF and DSP gain, a few fields for + * remembering/modifying gain settings (indexes). */ + struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE]; + + /* FAT channel info */ + s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ + s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ + s8 fat_min_power; /* always 0 */ + s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ + u8 fat_flags; /* flags copied from EEPROM */ + u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ + + /* Radio/DSP gain settings for each scan rate, for directed scans. */ + struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; +}; + +struct iwl4965_clip_group { + /* maximum power level to prevent clipping for each rate, derived by + * us from this band's saturation power in EEPROM */ + const s8 clip_powers[IWL_MAX_RATES]; +}; + +#include "iwl-4965-rs.h" + +#define IWL_TX_FIFO_AC0 0 +#define IWL_TX_FIFO_AC1 1 +#define IWL_TX_FIFO_AC2 2 +#define IWL_TX_FIFO_AC3 3 +#define IWL_TX_FIFO_HCCA_1 5 +#define IWL_TX_FIFO_HCCA_2 6 +#define IWL_TX_FIFO_NONE 7 + +/* Minimum number of queues. MAX_NUM is defined in hw specific files */ +#define IWL_MIN_NUM_QUEUES 4 + +/* Power management (not Tx power) structures */ + +struct iwl4965_power_vec_entry { + struct iwl4965_powertable_cmd cmd; + u8 no_dtim; +}; +#define IWL_POWER_RANGE_0 (0) +#define IWL_POWER_RANGE_1 (1) + +#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */ +#define IWL_POWER_INDEX_3 0x03 +#define IWL_POWER_INDEX_5 0x05 +#define IWL_POWER_AC 0x06 +#define IWL_POWER_BATTERY 0x07 +#define IWL_POWER_LIMIT 0x07 +#define IWL_POWER_MASK 0x0F +#define IWL_POWER_ENABLED 0x10 +#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK) + +struct iwl4965_power_mgr { + spinlock_t lock; + struct iwl4965_power_vec_entry pwr_range_0[IWL_POWER_AC]; + struct iwl4965_power_vec_entry pwr_range_1[IWL_POWER_AC]; + u8 active_index; + u32 dtim_val; +}; + +#define IEEE80211_DATA_LEN 2304 +#define IEEE80211_4ADDR_LEN 30 +#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) + +struct iwl4965_frame { + union { + struct ieee80211_hdr frame; + struct iwl4965_tx_beacon_cmd beacon; + u8 raw[IEEE80211_FRAME_LEN]; + u8 cmd[360]; + } u; + struct list_head list; +}; + +#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf) +#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8) +#define SEQ_TO_INDEX(x) (x & 0xff) +#define INDEX_TO_SEQ(x) (x & 0xff) +#define SEQ_HUGE_FRAME (0x4000) +#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000) +#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) +#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) +#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) + +enum { + /* CMD_SIZE_NORMAL = 0, */ + CMD_SIZE_HUGE = (1 << 0), + /* CMD_SYNC = 0, */ + CMD_ASYNC = (1 << 1), + /* CMD_NO_SKB = 0, */ + CMD_WANT_SKB = (1 << 2), +}; + +struct iwl4965_cmd; +struct iwl4965_priv; + +struct iwl4965_cmd_meta { + struct iwl4965_cmd_meta *source; + union { + struct sk_buff *skb; + int (*callback)(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct sk_buff *skb); + } __attribute__ ((packed)) u; + + /* The CMD_SIZE_HUGE flag bit indicates that the command + * structure is stored at the end of the shared queue memory. */ + u32 flags; + +} __attribute__ ((packed)); + +/** + * struct iwl4965_cmd + * + * For allocation of the command and tx queues, this establishes the overall + * size of the largest command we send to uCode, except for a scan command + * (which is relatively huge; space is allocated separately). + */ +struct iwl4965_cmd { + struct iwl4965_cmd_meta meta; /* driver data */ + struct iwl4965_cmd_header hdr; /* uCode API */ + union { + struct iwl4965_addsta_cmd addsta; + struct iwl4965_led_cmd led; + u32 flags; + u8 val8; + u16 val16; + u32 val32; + struct iwl4965_bt_cmd bt; + struct iwl4965_rxon_time_cmd rxon_time; + struct iwl4965_powertable_cmd powertable; + struct iwl4965_qosparam_cmd qosparam; + struct iwl4965_tx_cmd tx; + struct iwl4965_tx_beacon_cmd tx_beacon; + struct iwl4965_rxon_assoc_cmd rxon_assoc; + u8 *indirect; + u8 payload[360]; + } __attribute__ ((packed)) cmd; +} __attribute__ ((packed)); + +struct iwl4965_host_cmd { + u8 id; + u16 len; + struct iwl4965_cmd_meta meta; + const void *data; +}; + +#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl4965_cmd) - \ + sizeof(struct iwl4965_cmd_meta)) + +/* + * RX related structures and functions + */ +#define RX_FREE_BUFFERS 64 +#define RX_LOW_WATERMARK 8 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +/** + * struct iwl4965_rx_queue - Rx queue + * @processed: Internal index to last handled Rx packet + * @read: Shared index to newest available Rx buffer + * @write: Shared index to oldest written Rx packet + * @free_count: Number of pre-allocated buffers in rx_free + * @rx_free: list of free SKBs for use + * @rx_used: List of Rx buffers with no SKB + * @need_update: flag to indicate we need to update read/write index + * + * NOTE: rx_free and rx_used are used as a FIFO for iwl4965_rx_mem_buffers + */ +struct iwl4965_rx_queue { + __le32 *bd; + dma_addr_t dma_addr; + struct iwl4965_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; + struct iwl4965_rx_mem_buffer *queue[RX_QUEUE_SIZE]; + u32 processed; + u32 read; + u32 write; + u32 free_count; + struct list_head rx_free; + struct list_head rx_used; + int need_update; + spinlock_t lock; +}; + +#define IWL_SUPPORTED_RATES_IE_LEN 8 + +#define SCAN_INTERVAL 100 + +#define MAX_A_CHANNELS 252 +#define MIN_A_CHANNELS 7 + +#define MAX_B_CHANNELS 14 +#define MIN_B_CHANNELS 1 + +#define STATUS_HCMD_ACTIVE 0 /* host command in progress */ +#define STATUS_INT_ENABLED 1 +#define STATUS_RF_KILL_HW 2 +#define STATUS_RF_KILL_SW 3 +#define STATUS_INIT 4 +#define STATUS_ALIVE 5 +#define STATUS_READY 6 +#define STATUS_TEMPERATURE 7 +#define STATUS_GEO_CONFIGURED 8 +#define STATUS_EXIT_PENDING 9 +#define STATUS_IN_SUSPEND 10 +#define STATUS_STATISTICS 11 +#define STATUS_SCANNING 12 +#define STATUS_SCAN_ABORTING 13 +#define STATUS_SCAN_HW 14 +#define STATUS_POWER_PMI 15 +#define STATUS_FW_ERROR 16 + +#define MAX_TID_COUNT 9 + +#define IWL_INVALID_RATE 0xFF +#define IWL_INVALID_VALUE -1 + +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG +/** + * struct iwl4965_ht_agg -- aggregation status while waiting for block-ack + * @txq_id: Tx queue used for Tx attempt + * @frame_count: # frames attempted by Tx command + * @wait_for_ba: Expect block-ack before next Tx reply + * @start_idx: Index of 1st Transmit Frame Descriptor (TFD) in Tx window + * @bitmap0: Low order bitmap, one bit for each frame pending ACK in Tx window + * @bitmap1: High order, one bit for each frame pending ACK in Tx window + * @rate_n_flags: Rate at which Tx was attempted + * + * If REPLY_TX indicates that aggregation was attempted, driver must wait + * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info + * until block ack arrives. + */ +struct iwl4965_ht_agg { + u16 txq_id; + u16 frame_count; + u16 wait_for_ba; + u16 start_idx; + u32 bitmap0; + u32 bitmap1; + u32 rate_n_flags; +}; +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ + +struct iwl4965_tid_data { + u16 seq_number; +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG + struct iwl4965_ht_agg agg; +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ +}; + +struct iwl4965_hw_key { + enum ieee80211_key_alg alg; + int keylen; + u8 key[32]; +}; + +union iwl4965_ht_rate_supp { + u16 rates; + struct { + u8 siso_rate; + u8 mimo_rate; + }; +}; + +#ifdef CONFIG_IWL4965_HT +#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) +#define CFG_HT_MPDU_DENSITY_2USEC (0x5) +#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC + +struct iwl_ht_info { + /* self configuration data */ + u8 is_ht; + u8 supported_chan_width; + u16 tx_mimo_ps_mode; + u8 is_green_field; + u8 sgf; + u8 max_amsdu_size; + u8 ampdu_factor; + u8 mpdu_density; + u8 supp_mcs_set[16]; + /* BSS related data */ + u8 control_channel; + u8 extension_chan_offset; + u8 tx_chan_width; + u8 ht_protection; + u8 non_GF_STA_present; +}; +#endif /*CONFIG_IWL4965_HT */ + +#ifdef CONFIG_IWL4965_QOS + +union iwl4965_qos_capabity { + struct { + u8 edca_count:4; /* bit 0-3 */ + u8 q_ack:1; /* bit 4 */ + u8 queue_request:1; /* bit 5 */ + u8 txop_request:1; /* bit 6 */ + u8 reserved:1; /* bit 7 */ + } q_AP; + struct { + u8 acvo_APSD:1; /* bit 0 */ + u8 acvi_APSD:1; /* bit 1 */ + u8 ac_bk_APSD:1; /* bit 2 */ + u8 ac_be_APSD:1; /* bit 3 */ + u8 q_ack:1; /* bit 4 */ + u8 max_len:2; /* bit 5-6 */ + u8 more_data_ack:1; /* bit 7 */ + } q_STA; + u8 val; +}; + +/* QoS structures */ +struct iwl4965_qos_info { + int qos_enable; + int qos_active; + union iwl4965_qos_capabity qos_cap; + struct iwl4965_qosparam_cmd def_qos_parm; +}; +#endif /*CONFIG_IWL4965_QOS */ + +#define STA_PS_STATUS_WAKE 0 +#define STA_PS_STATUS_SLEEP 1 + +struct iwl4965_station_entry { + struct iwl4965_addsta_cmd sta; + struct iwl4965_tid_data tid[MAX_TID_COUNT]; + u8 used; + u8 ps_status; + struct iwl4965_hw_key keyinfo; +}; + +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + void *v_addr; /* access by driver */ + dma_addr_t p_addr; /* access by card's busmaster DMA */ + u32 len; /* bytes */ +}; + +/* uCode file layout */ +struct iwl4965_ucode { + __le32 ver; /* major/minor/subminor */ + __le32 inst_size; /* bytes of runtime instructions */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of initialization instructions */ + __le32 init_data_size; /* bytes of initialization data */ + __le32 boot_size; /* bytes of bootstrap instructions */ + u8 data[0]; /* data in same order as "size" elements */ +}; + +#define IWL_IBSS_MAC_HASH_SIZE 32 + +struct iwl4965_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num; + u16 frag_num; + unsigned long packet_time; + struct list_head list; +}; + +/** + * struct iwl4965_driver_hw_info + * @max_txq_num: Max # Tx queues supported + * @ac_queue_count: # Tx queues for EDCA Access Categories (AC) + * @tx_cmd_len: Size of Tx command (but not including frame itself) + * @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2) + * @rx_buffer_size: + * @max_rxq_log: Log-base-2 of max_rxq_size + * @max_stations: + * @bcast_sta_id: + * @shared_virt: Pointer to driver/uCode shared Tx Byte Counts and Rx status + * @shared_phys: Physical Pointer to Tx Byte Counts and Rx status + */ +struct iwl4965_driver_hw_info { + u16 max_txq_num; + u16 ac_queue_count; + u16 tx_cmd_len; + u16 max_rxq_size; + u32 rx_buf_size; + u32 max_pkt_size; + u16 max_rxq_log; + u8 max_stations; + u8 bcast_sta_id; + void *shared_virt; + dma_addr_t shared_phys; +}; + +#define HT_SHORT_GI_20MHZ_ONLY (1 << 0) +#define HT_SHORT_GI_40MHZ_ONLY (1 << 1) + + +#define IWL_RX_HDR(x) ((struct iwl4965_rx_frame_hdr *)(\ + x->u.rx_frame.stats.payload + \ + x->u.rx_frame.stats.phy_count)) +#define IWL_RX_END(x) ((struct iwl4965_rx_frame_end *)(\ + IWL_RX_HDR(x)->payload + \ + le16_to_cpu(IWL_RX_HDR(x)->len))) +#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) +#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) + + +/****************************************************************************** + * + * Functions implemented in iwl-base.c which are forward declared here + * for use by iwl-*.c + * + *****************************************************************************/ +struct iwl4965_addsta_cmd; +extern int iwl4965_send_add_station(struct iwl4965_priv *priv, + struct iwl4965_addsta_cmd *sta, u8 flags); +extern u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, + int is_ap, u8 flags, void *ht_data); +extern int iwl4965_is_network_packet(struct iwl4965_priv *priv, + struct ieee80211_hdr *header); +extern int iwl4965_power_init_handle(struct iwl4965_priv *priv); +extern int iwl4965_eeprom_init(struct iwl4965_priv *priv); +#ifdef CONFIG_IWL4965_DEBUG +extern void iwl4965_report_frame(struct iwl4965_priv *priv, + struct iwl4965_rx_packet *pkt, + struct ieee80211_hdr *header, int group100); +#else +static inline void iwl4965_report_frame(struct iwl4965_priv *priv, + struct iwl4965_rx_packet *pkt, + struct ieee80211_hdr *header, + int group100) {} +#endif +extern void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb, + void *data, short len, + struct ieee80211_rx_status *stats, + u16 phy_flags); +extern int iwl4965_is_duplicate_packet(struct iwl4965_priv *priv, + struct ieee80211_hdr *header); +extern int iwl4965_rx_queue_alloc(struct iwl4965_priv *priv); +extern void iwl4965_rx_queue_reset(struct iwl4965_priv *priv, + struct iwl4965_rx_queue *rxq); +extern int iwl4965_calc_db_from_ratio(int sig_ratio); +extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); +extern int iwl4965_tx_queue_init(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, int count, u32 id); +extern void iwl4965_rx_replenish(void *data); +extern void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq); +extern int iwl4965_send_cmd_pdu(struct iwl4965_priv *priv, u8 id, u16 len, + const void *data); +extern int __must_check iwl4965_send_cmd(struct iwl4965_priv *priv, + struct iwl4965_host_cmd *cmd); +extern unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv, + struct ieee80211_hdr *hdr, + const u8 *dest, int left); +extern int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv, + struct iwl4965_rx_queue *q); +extern int iwl4965_send_statistics_request(struct iwl4965_priv *priv); +extern void iwl4965_set_decrypted_flag(struct iwl4965_priv *priv, struct sk_buff *skb, + u32 decrypt_res, + struct ieee80211_rx_status *stats); +extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr); + +extern const u8 iwl4965_broadcast_addr[ETH_ALEN]; + +/* + * Currently used by iwl-3945-rs... look at restructuring so that it doesn't + * call this... todo... fix that. +*/ +extern u8 iwl4965_sync_station(struct iwl4965_priv *priv, int sta_id, + u16 tx_rate, u8 flags); + +/****************************************************************************** + * + * Functions implemented in iwl-[34]*.c which are forward declared here + * for use by iwl-base.c + * + * NOTE: The implementation of these functions are hardware specific + * which is why they are in the hardware specific files (vs. iwl-base.c) + * + * Naming convention -- + * iwl4965_ <-- Its part of iwlwifi (should be changed to iwl4965_) + * iwl4965_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) + * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) + * iwl4965_bg_ <-- Called from work queue context + * iwl4965_mac_ <-- mac80211 callback + * + ****************************************************************************/ +extern void iwl4965_hw_rx_handler_setup(struct iwl4965_priv *priv); +extern void iwl4965_hw_setup_deferred_work(struct iwl4965_priv *priv); +extern void iwl4965_hw_cancel_deferred_work(struct iwl4965_priv *priv); +extern int iwl4965_hw_rxq_stop(struct iwl4965_priv *priv); +extern int iwl4965_hw_set_hw_setting(struct iwl4965_priv *priv); +extern int iwl4965_hw_nic_init(struct iwl4965_priv *priv); +extern int iwl4965_hw_nic_stop_master(struct iwl4965_priv *priv); +extern void iwl4965_hw_txq_ctx_free(struct iwl4965_priv *priv); +extern void iwl4965_hw_txq_ctx_stop(struct iwl4965_priv *priv); +extern int iwl4965_hw_nic_reset(struct iwl4965_priv *priv); +extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl4965_priv *priv, void *tfd, + dma_addr_t addr, u16 len); +extern int iwl4965_hw_txq_free_tfd(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq); +extern int iwl4965_hw_get_temperature(struct iwl4965_priv *priv); +extern int iwl4965_hw_tx_queue_init(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq); +extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl4965_priv *priv, + struct iwl4965_frame *frame, u8 rate); +extern int iwl4965_hw_get_rx_read(struct iwl4965_priv *priv); +extern void iwl4965_hw_build_tx_cmd_rate(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, + struct ieee80211_tx_control *ctrl, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id); +extern int iwl4965_hw_reg_send_txpower(struct iwl4965_priv *priv); +extern int iwl4965_hw_reg_set_txpower(struct iwl4965_priv *priv, s8 power); +extern void iwl4965_hw_rx_statistics(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb); +extern void iwl4965_disable_events(struct iwl4965_priv *priv); +extern int iwl4965_get_temperature(const struct iwl4965_priv *priv); + +/** + * iwl4965_hw_find_station - Find station id for a given BSSID + * @bssid: MAC address of station ID to find + * + * NOTE: This should not be hardware specific but the code has + * not yet been merged into a single common layer for managing the + * station tables. + */ +extern u8 iwl4965_hw_find_station(struct iwl4965_priv *priv, const u8 *bssid); + +extern int iwl4965_hw_channel_switch(struct iwl4965_priv *priv, u16 channel); +extern int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index); + +struct iwl4965_priv; /* * Forward declare iwl-4965.c functions for iwl-base.c */ -extern int iwl_eeprom_aqcuire_semaphore(struct iwl_priv *priv); -extern void iwl_eeprom_release_semaphore(struct iwl_priv *priv); +extern int iwl4965_eeprom_acquire_semaphore(struct iwl4965_priv *priv); +extern void iwl4965_eeprom_release_semaphore(struct iwl4965_priv *priv); -extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, - struct iwl_tx_queue *txq, +extern int iwl4965_tx_queue_update_wr_ptr(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, u16 byte_cnt); -extern void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, +extern void iwl4965_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap); -extern void iwl4965_set_rxon_ht(struct iwl_priv *priv, - struct sta_ht_info *ht_info); - -extern void iwl4965_set_rxon_chain(struct iwl_priv *priv); -extern int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd, +extern void iwl4965_set_rxon_chain(struct iwl4965_priv *priv); +extern int iwl4965_tx_cmd(struct iwl4965_priv *priv, struct iwl4965_cmd *out_cmd, u8 sta_id, dma_addr_t txcmd_phys, struct ieee80211_hdr *hdr, u8 hdr_len, struct ieee80211_tx_control *ctrl, void *sta_in); -extern int iwl4965_init_hw_rates(struct iwl_priv *priv, - struct ieee80211_rate *rates); -extern int iwl4965_alive_notify(struct iwl_priv *priv); -extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); -extern void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index); - -extern void iwl4965_chain_noise_reset(struct iwl_priv *priv); -extern void iwl4965_init_sensitivity(struct iwl_priv *priv, u8 flags, +extern int iwl4965_alive_notify(struct iwl4965_priv *priv); +extern void iwl4965_update_rate_scaling(struct iwl4965_priv *priv, u8 mode); +extern void iwl4965_chain_noise_reset(struct iwl4965_priv *priv); +extern void iwl4965_init_sensitivity(struct iwl4965_priv *priv, u8 flags, u8 force); -extern int iwl4965_set_fat_chan_info(struct iwl_priv *priv, int phymode, +extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, int phymode, u16 channel, - const struct iwl_eeprom_channel *eeprom_ch, + const struct iwl4965_eeprom_channel *eeprom_ch, u8 fat_extension_channel); -extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); +extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG -extern int iwl_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, +#ifdef CONFIG_IWL4965_HT +extern void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, + int mode); +extern void iwl4965_set_rxon_ht(struct iwl4965_priv *priv, + struct iwl_ht_info *ht_info); +extern void iwl4965_set_ht_add_station(struct iwl4965_priv *priv, u8 index, + struct ieee80211_ht_info *sta_ht_inf); +#ifdef CONFIG_IWL4965_HT_AGG +extern int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, u16 *start_seq_num); -extern int iwl_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da, +extern int iwl4965_mac_ht_rx_agg_start(struct ieee80211_hw *hw, u8 *da, u16 tid, u16 start_seq_num); -extern int iwl_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da, +extern int iwl4965_mac_ht_rx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, int generator); -extern int iwl_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, +extern int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, u8 *da, u16 tid, int generator); -extern void iwl4965_turn_off_agg(struct iwl_priv *priv, u8 tid); -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /*CONFIG_IWLWIFI_HT */ +extern void iwl4965_turn_off_agg(struct iwl4965_priv *priv, u8 tid); +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /*CONFIG_IWL4965_HT */ /* Structures, enum, and defines specific to the 4965 */ #define IWL4965_KW_SIZE 0x1000 /*4k */ -struct iwl_kw { +struct iwl4965_kw { dma_addr_t dma_addr; void *v_addr; size_t size; @@ -120,21 +858,9 @@ struct iwl_kw { #define NRG_NUM_PREV_STAT_L 20 #define NUM_RX_CHAINS (3) -#define TX_POWER_IWL_ILLEGAL_VDET -100000 #define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000 -#define TX_POWER_IWL_CLOSED_LOOP_MIN_POWER 18 -#define TX_POWER_IWL_CLOSED_LOOP_MAX_POWER 34 -#define TX_POWER_IWL_VDET_SLOPE_BELOW_NOMINAL 17 -#define TX_POWER_IWL_VDET_SLOPE_ABOVE_NOMINAL 20 -#define TX_POWER_IWL_NOMINAL_POWER 26 -#define TX_POWER_IWL_CLOSED_LOOP_ITERATION_LIMIT 1 -#define TX_POWER_IWL_VOLTAGE_CODES_PER_03V 7 -#define TX_POWER_IWL_DEGREES_PER_VDET_CODE 11 -#define IWL_TX_POWER_MAX_NUM_PA_MEASUREMENTS 1 -#define IWL_TX_POWER_CCK_COMPENSATION_B_STEP (9) -#define IWL_TX_POWER_CCK_COMPENSATION_C_STEP (5) - -struct iwl_traffic_load { + +struct iwl4965_traffic_load { unsigned long time_stamp; u32 packet_count[TID_QUEUE_MAX_SIZE]; u8 queue_count; @@ -142,8 +868,13 @@ struct iwl_traffic_load { u32 total; }; -#ifdef CONFIG_IWLWIFI_HT_AGG -struct iwl_agg_control { +#ifdef CONFIG_IWL4965_HT_AGG +/** + * struct iwl4965_agg_control + * @requested_ba: bit map of tids requesting aggregation/block-ack + * @granted_ba: bit map of tids granted aggregation/block-ack + */ +struct iwl4965_agg_control { unsigned long next_retry; u32 wait_for_agg_status; u32 tid_retry; @@ -152,13 +883,13 @@ struct iwl_agg_control { u8 auto_agg; u32 tid_traffic_load_threshold; u32 ba_timeout; - struct iwl_traffic_load traffic_load[TID_MAX_LOAD_COUNT]; + struct iwl4965_traffic_load traffic_load[TID_MAX_LOAD_COUNT]; }; -#endif /*CONFIG_IWLWIFI_HT_AGG */ +#endif /*CONFIG_IWL4965_HT_AGG */ -struct iwl_lq_mngr { -#ifdef CONFIG_IWLWIFI_HT_AGG - struct iwl_agg_control agg_ctrl; +struct iwl4965_lq_mngr { +#ifdef CONFIG_IWL4965_HT_AGG + struct iwl4965_agg_control agg_ctrl; #endif spinlock_t lock; s32 max_window_size; @@ -179,22 +910,6 @@ struct iwl_lq_mngr { #define CAL_NUM_OF_BEACONS 20 #define MAXIMUM_ALLOWED_PATHLOSS 15 -/* Param table within SENSITIVITY_CMD */ -#define HD_MIN_ENERGY_CCK_DET_INDEX (0) -#define HD_MIN_ENERGY_OFDM_DET_INDEX (1) -#define HD_AUTO_CORR32_X1_TH_ADD_MIN_INDEX (2) -#define HD_AUTO_CORR32_X1_TH_ADD_MIN_MRC_INDEX (3) -#define HD_AUTO_CORR40_X4_TH_ADD_MIN_MRC_INDEX (4) -#define HD_AUTO_CORR32_X4_TH_ADD_MIN_INDEX (5) -#define HD_AUTO_CORR32_X4_TH_ADD_MIN_MRC_INDEX (6) -#define HD_BARKER_CORR_TH_ADD_MIN_INDEX (7) -#define HD_BARKER_CORR_TH_ADD_MIN_MRC_INDEX (8) -#define HD_AUTO_CORR40_X4_TH_ADD_MIN_INDEX (9) -#define HD_OFDM_ENERGY_TH_IN_INDEX (10) - -#define SENSITIVITY_CMD_CONTROL_DEFAULT_TABLE __constant_cpu_to_le16(0) -#define SENSITIVITY_CMD_CONTROL_WORK_TABLE __constant_cpu_to_le16(1) - #define CHAIN_NOISE_MAX_DELTA_GAIN_CODE 3 #define MAX_FA_OFDM 50 @@ -222,8 +937,6 @@ struct iwl_lq_mngr { #define AUTO_CORR_STEP_CCK 3 #define AUTO_CORR_MAX_TH_CCK 160 -#define NRG_ALG 0 -#define AUTO_CORR_ALG 1 #define NRG_DIFF 2 #define NRG_STEP_CCK 2 #define NRG_MARGIN 8 @@ -239,24 +952,24 @@ struct iwl_lq_mngr { #define IN_BAND_FILTER 0xFF #define MIN_AVERAGE_NOISE_MAX_VALUE 0xFFFFFFFF -enum iwl_false_alarm_state { +enum iwl4965_false_alarm_state { IWL_FA_TOO_MANY = 0, IWL_FA_TOO_FEW = 1, IWL_FA_GOOD_RANGE = 2, }; -enum iwl_chain_noise_state { +enum iwl4965_chain_noise_state { IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */ IWL_CHAIN_NOISE_ACCUMULATE = 1, IWL_CHAIN_NOISE_CALIBRATED = 2, }; -enum iwl_sensitivity_state { +enum iwl4965_sensitivity_state { IWL_SENS_CALIB_ALLOWED = 0, IWL_SENS_CALIB_NEED_REINIT = 1, }; -enum iwl_calib_enabled_state { +enum iwl4965_calib_enabled_state { IWL_CALIB_DISABLED = 0, /* must be 0 */ IWL_CALIB_ENABLED = 1, }; @@ -271,7 +984,7 @@ struct statistics_general_data { }; /* Sensitivity calib data */ -struct iwl_sensitivity_data { +struct iwl4965_sensitivity_data { u32 auto_corr_ofdm; u32 auto_corr_ofdm_mrc; u32 auto_corr_ofdm_x1; @@ -300,7 +1013,7 @@ struct iwl_sensitivity_data { }; /* Chain noise (differential Rx gain) calib data */ -struct iwl_chain_noise_data { +struct iwl4965_chain_noise_data { u8 state; u16 beacon_count; u32 chain_noise_a; @@ -314,28 +1027,323 @@ struct iwl_chain_noise_data { u8 radio_write; }; -/* IWL4965 */ -#define RATE_MCS_CODE_MSK 0x7 -#define RATE_MCS_MIMO_POS 3 -#define RATE_MCS_MIMO_MSK 0x8 -#define RATE_MCS_HT_DUP_POS 5 -#define RATE_MCS_HT_DUP_MSK 0x20 -#define RATE_MCS_FLAGS_POS 8 -#define RATE_MCS_HT_POS 8 -#define RATE_MCS_HT_MSK 0x100 -#define RATE_MCS_CCK_POS 9 -#define RATE_MCS_CCK_MSK 0x200 -#define RATE_MCS_GF_POS 10 -#define RATE_MCS_GF_MSK 0x400 - -#define RATE_MCS_FAT_POS 11 -#define RATE_MCS_FAT_MSK 0x800 -#define RATE_MCS_DUP_POS 12 -#define RATE_MCS_DUP_MSK 0x1000 -#define RATE_MCS_SGI_POS 13 -#define RATE_MCS_SGI_MSK 0x2000 - -#define EEPROM_SEM_TIMEOUT 10 -#define EEPROM_SEM_RETRY_LIMIT 1000 - -#endif /* __iwl_4965_h__ */ +#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ +#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ + + +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT + +enum { + MEASUREMENT_READY = (1 << 0), + MEASUREMENT_ACTIVE = (1 << 1), +}; + +#endif + +struct iwl4965_priv { + + /* ieee device used by generic ieee processing code */ + struct ieee80211_hw *hw; + struct ieee80211_channel *ieee_channels; + struct ieee80211_rate *ieee_rates; + struct ieee80211_conf *cache_conf; + + /* temporary frame storage list */ + struct list_head free_frames; + int frames_count; + + u8 phymode; + int alloc_rxb_skb; + + void (*rx_handlers[REPLY_MAX])(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb); + + const struct ieee80211_hw_mode *modes; + +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT + /* spectrum measurement report caching */ + struct iwl4965_spectrum_notification measure_report; + u8 measurement_status; +#endif + /* ucode beacon time */ + u32 ucode_beacon_time; + + /* we allocate array of iwl4965_channel_info for NIC's valid channels. + * Access via channel # using indirect index array */ + struct iwl4965_channel_info *channel_info; /* channel info array */ + u8 channel_count; /* # of channels */ + + /* each calibration channel group in the EEPROM has a derived + * clip setting for each rate. */ + const struct iwl4965_clip_group clip_groups[5]; + + /* thermal calibration */ + s32 temperature; /* degrees Kelvin */ + s32 last_temperature; + + /* Scan related variables */ + unsigned long last_scan_jiffies; + unsigned long next_scan_jiffies; + unsigned long scan_start; + unsigned long scan_pass_start; + unsigned long scan_start_tsf; + int scan_bands; + int one_direct_scan; + u8 direct_ssid_len; + u8 direct_ssid[IW_ESSID_MAX_SIZE]; + struct iwl4965_scan_cmd *scan; + u8 only_active_channel; + + /* spinlock */ + spinlock_t lock; /* protect general shared data */ + spinlock_t hcmd_lock; /* protect hcmd */ + struct mutex mutex; + + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; + + /* uCode images, save to reload in case of failure */ + struct fw_desc ucode_code; /* runtime inst */ + struct fw_desc ucode_data; /* runtime data original */ + struct fw_desc ucode_data_backup; /* runtime data save/restore */ + struct fw_desc ucode_init; /* initialization inst */ + struct fw_desc ucode_init_data; /* initialization data */ + struct fw_desc ucode_boot; /* bootstrap inst */ + + + struct iwl4965_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 iwl4965_rxon_cmd active_rxon; + struct iwl4965_rxon_cmd staging_rxon; + + int error_recovering; + struct iwl4965_rxon_cmd recovery_rxon; + + /* 1st responses from initialize and runtime uCode images. + * 4965's initialize alive response contains some calibration data. */ + struct iwl4965_init_alive_resp card_alive_init; + struct iwl4965_alive_resp card_alive; + +#ifdef LED + /* LED related variables */ + struct iwl4965_activity_blink activity; + unsigned long led_packets; + int led_state; +#endif + + u16 active_rate; + u16 active_rate_basic; + + u8 call_post_assoc_from_beacon; + u8 assoc_station_added; + u8 use_ant_b_for_management_frame; /* Tx antenna selection */ + u8 valid_antenna; /* Bit mask of antennas actually connected */ +#ifdef CONFIG_IWL4965_SENSITIVITY + struct iwl4965_sensitivity_data sensitivity_data; + struct iwl4965_chain_noise_data chain_noise_data; + u8 start_calib; + __le16 sensitivity_tbl[HD_TABLE_SIZE]; +#endif /*CONFIG_IWL4965_SENSITIVITY*/ + +#ifdef CONFIG_IWL4965_HT + struct iwl_ht_info current_ht_config; +#endif + u8 last_phy_res[100]; + + /* Rate scaling data */ + struct iwl4965_lq_mngr lq_mngr; + + /* Rate scaling data */ + s8 data_retry_limit; + u8 retry_rate; + + wait_queue_head_t wait_command_queue; + + int activity_timer_active; + + /* Rx and Tx DMA processing queues */ + struct iwl4965_rx_queue rxq; + struct iwl4965_tx_queue txq[IWL_MAX_NUM_QUEUES]; + unsigned long txq_ctx_active_msk; + struct iwl4965_kw kw; /* keep warm address */ + u32 scd_base_addr; /* scheduler sram base address */ + + unsigned long status; + u32 config; + + int last_rx_rssi; /* From Rx packet statisitics */ + int last_rx_noise; /* From beacon statistics */ + + struct iwl4965_power_mgr power_data; + + struct iwl4965_notif_statistics statistics; + unsigned long last_statistics_time; + + /* context information */ + u8 essid[IW_ESSID_MAX_SIZE]; + u8 essid_len; + u16 rates_mask; + + u32 power_mode; + u32 antenna; + u8 bssid[ETH_ALEN]; + u16 rts_threshold; + u8 mac_addr[ETH_ALEN]; + + /*station table variables */ + spinlock_t sta_lock; + int num_stations; + struct iwl4965_station_entry stations[IWL_STATION_COUNT]; + + /* Indication if ieee80211_ops->open has been called */ + int is_open; + + u8 mac80211_registered; + int is_abg; + + u32 notif_missed_beacons; + + /* Rx'd packet timing information */ + u32 last_beacon_time; + u64 last_tsf; + + /* Duplicate packet detection */ + u16 last_seq_num; + u16 last_frag_num; + unsigned long last_packet_time; + + /* Hash table for finding stations in IBSS network */ + struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; + + /* eeprom */ + struct iwl4965_eeprom eeprom; + + int iw_mode; + + struct sk_buff *ibss_beacon; + + /* Last Rx'd beacon timestamp */ + u32 timestamp0; + u32 timestamp1; + u16 beacon_int; + struct iwl4965_driver_hw_info hw_setting; + int interface_id; + + /* Current association information needed to configure the + * hardware */ + u16 assoc_id; + u16 assoc_capability; + u8 ps_mode; + +#ifdef CONFIG_IWL4965_QOS + struct iwl4965_qos_info qos_data; +#endif /*CONFIG_IWL4965_QOS */ + + struct workqueue_struct *workqueue; + + struct work_struct up; + struct work_struct restart; + struct work_struct calibrated_work; + struct work_struct scan_completed; + struct work_struct rx_replenish; + struct work_struct rf_kill; + struct work_struct abort_scan; + struct work_struct update_link_led; + struct work_struct auth_work; + struct work_struct report_work; + struct work_struct request_scan; + struct work_struct beacon_update; + + struct tasklet_struct irq_tasklet; + + struct delayed_work init_alive_start; + struct delayed_work alive_start; + struct delayed_work activity_timer; + struct delayed_work thermal_periodic; + struct delayed_work gather_stats; + struct delayed_work scan_check; + struct delayed_work post_associate; + +#define IWL_DEFAULT_TX_POWER 0x0F + s8 user_txpower_limit; + s8 max_channel_txpower_limit; + +#ifdef CONFIG_PM + u32 pm_state[16]; +#endif + +#ifdef CONFIG_IWL4965_DEBUG + /* debugging info */ + u32 framecnt_to_us; + atomic_t restrict_refcnt; +#endif + + struct work_struct txpower_work; +#ifdef CONFIG_IWL4965_SENSITIVITY + struct work_struct sensitivity_work; +#endif + struct work_struct statistics_work; + struct timer_list statistics_periodic; + +#ifdef CONFIG_IWL4965_HT_AGG + struct work_struct agg_work; +#endif +}; /*iwl4965_priv */ + +static inline int iwl4965_is_associated(struct iwl4965_priv *priv) +{ + return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int is_channel_valid(const struct iwl4965_channel_info *ch_info) +{ + if (ch_info == NULL) + return 0; + return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; +} + +static inline int is_channel_narrow(const struct iwl4965_channel_info *ch_info) +{ + return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0; +} + +static inline int is_channel_radar(const struct iwl4965_channel_info *ch_info) +{ + return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; +} + +static inline u8 is_channel_a_band(const struct iwl4965_channel_info *ch_info) +{ + return ch_info->phymode == MODE_IEEE80211A; +} + +static inline u8 is_channel_bg_band(const struct iwl4965_channel_info *ch_info) +{ + return ((ch_info->phymode == MODE_IEEE80211B) || + (ch_info->phymode == MODE_IEEE80211G)); +} + +static inline int is_channel_passive(const struct iwl4965_channel_info *ch) +{ + return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; +} + +static inline int is_channel_ibss(const struct iwl4965_channel_info *ch) +{ + return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; +} + +extern const struct iwl4965_channel_info *iwl4965_get_channel_info( + const struct iwl4965_priv *priv, int phymode, u16 channel); + +/* Requires full declaration of iwl4965_priv before including */ +#include "iwl-4965-io.h" + +#endif /* __iwl4965_4965_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-channel.h b/drivers/net/wireless/iwlwifi/iwl-channel.h deleted file mode 100644 index 023c3f2..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-channel.h +++ /dev/null @@ -1,161 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2005 - 2007 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. - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ -#ifndef __iwl_channel_h__ -#define __iwl_channel_h__ - -#define IWL_NUM_SCAN_RATES (2) - -struct iwl_channel_tgd_info { - u8 type; - s8 max_power; -}; - -struct iwl_channel_tgh_info { - s64 last_radar_time; -}; - -/* current Tx power values to use, one for each rate for each channel. - * requested power is limited by: - * -- regulatory EEPROM limits for this channel - * -- hardware capabilities (clip-powers) - * -- spectrum management - * -- user preference (e.g. iwconfig) - * when requested power is set, base power index must also be set. */ -struct iwl_channel_power_info { - struct iwl_tx_power tpc; /* actual radio and DSP gain settings */ - s8 power_table_index; /* actual (compenst'd) index into gain table */ - s8 base_power_index; /* gain index for power at factory temp. */ - s8 requested_power; /* power (dBm) requested for this chnl/rate */ -}; - -/* current scan Tx power values to use, one for each scan rate for each - * channel. */ -struct iwl_scan_power_info { - struct iwl_tx_power tpc; /* actual radio and DSP gain settings */ - s8 power_table_index; /* actual (compenst'd) index into gain table */ - s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ -}; - -/* Channel unlock period is 15 seconds. If no beacon or probe response - * has been received within 15 seconds on a locked channel then the channel - * remains locked. */ -#define TX_UNLOCK_PERIOD 15 - -/* CSA lock period is 15 seconds. If a CSA has been received on a channel in - * the last 15 seconds, the channel is locked */ -#define CSA_LOCK_PERIOD 15 -/* - * One for each channel, holds all channel setup data - * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant - * with one another! - */ -#define IWL4965_MAX_RATE (33) - -struct iwl_channel_info { - struct iwl_channel_tgd_info tgd; - struct iwl_channel_tgh_info tgh; - struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */ - struct iwl_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for - * FAT channel */ - - u8 channel; /* channel number */ - u8 flags; /* flags copied from EEPROM */ - s8 max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ - s8 curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ - s8 min_power; /* always 0 */ - s8 scan_power; /* (dBm) regul. eeprom, direct scans, any rate */ - - u8 group_index; /* 0-4, maps channel to group1/2/3/4/5 */ - u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ - u8 phymode; /* MODE_IEEE80211{A,B,G} */ - - /* Radio/DSP gain settings for each "normal" data Tx rate. - * These include, in addition to RF and DSP gain, a few fields for - * remembering/modifying gain settings (indexes). */ - struct iwl_channel_power_info power_info[IWL4965_MAX_RATE]; - -#if IWL == 4965 - /* FAT channel info */ - s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ - s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ - s8 fat_min_power; /* always 0 */ - s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ - u8 fat_flags; /* flags copied from EEPROM */ - u8 fat_extension_channel; -#endif - - /* Radio/DSP gain settings for each scan rate, for directed scans. */ - struct iwl_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; -}; - -struct iwl_clip_group { - /* maximum power level to prevent clipping for each rate, derived by - * us from this band's saturation power in EEPROM */ - const s8 clip_powers[IWL_MAX_RATES]; -}; - -static inline int is_channel_valid(const struct iwl_channel_info *ch_info) -{ - if (ch_info == NULL) - return 0; - return (ch_info->flags & EEPROM_CHANNEL_VALID) ? 1 : 0; -} - -static inline int is_channel_narrow(const struct iwl_channel_info *ch_info) -{ - return (ch_info->flags & EEPROM_CHANNEL_NARROW) ? 1 : 0; -} - -static inline int is_channel_radar(const struct iwl_channel_info *ch_info) -{ - return (ch_info->flags & EEPROM_CHANNEL_RADAR) ? 1 : 0; -} - -static inline u8 is_channel_a_band(const struct iwl_channel_info *ch_info) -{ - return ch_info->phymode == MODE_IEEE80211A; -} - -static inline u8 is_channel_bg_band(const struct iwl_channel_info *ch_info) -{ - return ((ch_info->phymode == MODE_IEEE80211B) || - (ch_info->phymode == MODE_IEEE80211G)); -} - -static inline int is_channel_passive(const struct iwl_channel_info *ch) -{ - return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; -} - -static inline int is_channel_ibss(const struct iwl_channel_info *ch) -{ - return ((ch->flags & EEPROM_CHANNEL_IBSS)) ? 1 : 0; -} - -extern const struct iwl_channel_info *iwl_get_channel_info( - const struct iwl_priv *priv, int phymode, u16 channel); - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h deleted file mode 100644 index 9de8d7f..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ /dev/null @@ -1,1734 +0,0 @@ -/****************************************************************************** - * - * 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) 2005 - 2007 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 Geeral 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2007 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. - * - *****************************************************************************/ - -#ifndef __iwl_commands_h__ -#define __iwl_commands_h__ - -enum { - REPLY_ALIVE = 0x1, - REPLY_ERROR = 0x2, - - /* RXON and QOS commands */ - REPLY_RXON = 0x10, - REPLY_RXON_ASSOC = 0x11, - REPLY_QOS_PARAM = 0x13, - REPLY_RXON_TIMING = 0x14, - - /* Multi-Station support */ - REPLY_ADD_STA = 0x18, - REPLY_REMOVE_STA = 0x19, /* not used */ - REPLY_REMOVE_ALL_STA = 0x1a, /* not used */ - - /* RX, TX, LEDs */ -#if IWL == 3945 - REPLY_3945_RX = 0x1b, /* 3945 only */ -#endif - REPLY_TX = 0x1c, - REPLY_RATE_SCALE = 0x47, /* 3945 only */ - REPLY_LEDS_CMD = 0x48, - REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* 4965 only */ - - /* 802.11h related */ - RADAR_NOTIFICATION = 0x70, /* not used */ - REPLY_QUIET_CMD = 0x71, /* not used */ - REPLY_CHANNEL_SWITCH = 0x72, - CHANNEL_SWITCH_NOTIFICATION = 0x73, - REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74, - SPECTRUM_MEASURE_NOTIFICATION = 0x75, - - /* Power Management */ - POWER_TABLE_CMD = 0x77, - PM_SLEEP_NOTIFICATION = 0x7A, - PM_DEBUG_STATISTIC_NOTIFIC = 0x7B, - - /* Scan commands and notifications */ - REPLY_SCAN_CMD = 0x80, - REPLY_SCAN_ABORT_CMD = 0x81, - SCAN_START_NOTIFICATION = 0x82, - SCAN_RESULTS_NOTIFICATION = 0x83, - SCAN_COMPLETE_NOTIFICATION = 0x84, - - /* IBSS/AP commands */ - BEACON_NOTIFICATION = 0x90, - REPLY_TX_BEACON = 0x91, - WHO_IS_AWAKE_NOTIFICATION = 0x94, /* not used */ - - /* Miscellaneous commands */ - QUIET_NOTIFICATION = 0x96, /* not used */ - REPLY_TX_PWR_TABLE_CMD = 0x97, - MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ - - /* BT config command */ - REPLY_BT_CONFIG = 0x9b, - - /* 4965 Statistics */ - REPLY_STATISTICS_CMD = 0x9c, - STATISTICS_NOTIFICATION = 0x9d, - - /* RF-KILL commands and notifications */ - REPLY_CARD_STATE_CMD = 0xa0, - CARD_STATE_NOTIFICATION = 0xa1, - - /* Missed beacons notification */ - MISSED_BEACONS_NOTIFICATION = 0xa2, - -#if IWL == 4965 - REPLY_CT_KILL_CONFIG_CMD = 0xa4, - SENSITIVITY_CMD = 0xa8, - REPLY_PHY_CALIBRATION_CMD = 0xb0, - REPLY_RX_PHY_CMD = 0xc0, - REPLY_RX_MPDU_CMD = 0xc1, - REPLY_4965_RX = 0xc3, - REPLY_COMPRESSED_BA = 0xc5, -#endif - REPLY_MAX = 0xff -}; - -/****************************************************************************** - * (0) - * Header - * - *****************************************************************************/ - -#define IWL_CMD_FAILED_MSK 0x40 - -struct iwl_cmd_header { - u8 cmd; - u8 flags; - /* We have 15 LSB to use as we please (MSB indicates - * a frame Rx'd from the HW). We encode the following - * information into the sequence field: - * - * 0:7 index in fifo - * 8:13 fifo selection - * 14:14 bit indicating if this packet references the 'extra' - * storage at the end of the memory queue - * 15:15 (Rx indication) - * - */ - __le16 sequence; - - /* command data follows immediately */ - u8 data[0]; -} __attribute__ ((packed)); - -/****************************************************************************** - * (0a) - * Alive and Error Commands & Responses: - * - *****************************************************************************/ - -#define UCODE_VALID_OK __constant_cpu_to_le32(0x1) -#define INITIALIZE_SUBTYPE (9) - -/* - * REPLY_ALIVE = 0x1 (response only, not a command) - */ -struct iwl_alive_resp { - u8 ucode_minor; - u8 ucode_major; - __le16 reserved1; - u8 sw_rev[8]; - u8 ver_type; - u8 ver_subtype; - __le16 reserved2; - __le32 log_event_table_ptr; - __le32 error_event_table_ptr; - __le32 timestamp; - __le32 is_valid; -} __attribute__ ((packed)); - -struct iwl_init_alive_resp { - u8 ucode_minor; - u8 ucode_major; - __le16 reserved1; - u8 sw_rev[8]; - u8 ver_type; - u8 ver_subtype; - __le16 reserved2; - __le32 log_event_table_ptr; - __le32 error_event_table_ptr; - __le32 timestamp; - __le32 is_valid; - -#if IWL == 4965 - /* calibration values from "initialize" uCode */ - __le32 voltage; /* signed */ - __le32 therm_r1[2]; /* signed 1st for normal, 2nd for FAT channel */ - __le32 therm_r2[2]; /* signed */ - __le32 therm_r3[2]; /* signed */ - __le32 therm_r4[2]; /* signed */ - __le32 tx_atten[5][2]; /* signed MIMO gain comp, 5 freq groups, - * 2 Tx chains */ -#endif -} __attribute__ ((packed)); - -union tsf { - u8 byte[8]; - __le16 word[4]; - __le32 dw[2]; -}; - -/* - * REPLY_ERROR = 0x2 (response only, not a command) - */ -struct iwl_error_resp { - __le32 error_type; - u8 cmd_id; - u8 reserved1; - __le16 bad_cmd_seq_num; -#if IWL == 3945 - __le16 reserved2; -#endif - __le32 error_info; - union tsf timestamp; -} __attribute__ ((packed)); - -/****************************************************************************** - * (1) - * RXON Commands & Responses: - * - *****************************************************************************/ - -/* - * Rx config defines & structure - */ -/* rx_config device types */ -enum { - RXON_DEV_TYPE_AP = 1, - RXON_DEV_TYPE_ESS = 3, - RXON_DEV_TYPE_IBSS = 4, - RXON_DEV_TYPE_SNIFFER = 6, -}; - -/* rx_config flags */ -/* band & modulation selection */ -#define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) -#define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) -/* auto detection enable */ -#define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) -/* TGg protection when tx */ -#define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) -/* cck short slot & preamble */ -#define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) -#define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) -/* antenna selection */ -#define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) -#define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) -#define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) -#define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) -/* radar detection enable */ -#define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) -#define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) -/* rx response to host with 8-byte TSF -* (according to ON_AIR deassertion) */ -#define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) - -/* rx_config filter flags */ -/* accept all data frames */ -#define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) -/* pass control & management to host */ -#define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) -/* accept multi-cast */ -#define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) -/* don't decrypt uni-cast frames */ -#define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) -/* don't decrypt multi-cast frames */ -#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) -/* STA is associated */ -#define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) -/* transfer to host non bssid beacons in associated state */ -#define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) - -/* - * REPLY_RXON = 0x10 (command, has simple generic response) - */ -struct iwl_rxon_cmd { - u8 node_addr[6]; - __le16 reserved1; - u8 bssid_addr[6]; - __le16 reserved2; - u8 wlap_bssid_addr[6]; - __le16 reserved3; - u8 dev_type; - u8 air_propagation; -#if IWL == 3945 - __le16 reserved4; -#elif IWL == 4965 - __le16 rx_chain; -#endif - u8 ofdm_basic_rates; - u8 cck_basic_rates; - __le16 assoc_id; - __le32 flags; - __le32 filter_flags; - __le16 channel; -#if IWL == 3945 - __le16 reserved5; -#elif IWL == 4965 - u8 ofdm_ht_single_stream_basic_rates; - u8 ofdm_ht_dual_stream_basic_rates; -#endif -} __attribute__ ((packed)); - -/* - * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) - */ -struct iwl_rxon_assoc_cmd { - __le32 flags; - __le32 filter_flags; - u8 ofdm_basic_rates; - u8 cck_basic_rates; -#if IWL == 4965 - u8 ofdm_ht_single_stream_basic_rates; - u8 ofdm_ht_dual_stream_basic_rates; - __le16 rx_chain_select_flags; -#endif - __le16 reserved; -} __attribute__ ((packed)); - -/* - * REPLY_RXON_TIMING = 0x14 (command, has simple generic response) - */ -struct iwl_rxon_time_cmd { - union tsf timestamp; - __le16 beacon_interval; - __le16 atim_window; - __le32 beacon_init_val; - __le16 listen_interval; - __le16 reserved; -} __attribute__ ((packed)); - -struct iwl_tx_power { - u8 tx_gain; /* gain for analog radio */ - u8 dsp_atten; /* gain for DSP */ -} __attribute__ ((packed)); - -#if IWL == 3945 -struct iwl_power_per_rate { - u8 rate; /* plcp */ - struct iwl_tx_power tpc; - u8 reserved; -} __attribute__ ((packed)); - -#elif IWL == 4965 -#define POWER_TABLE_NUM_ENTRIES 33 -#define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 -#define POWER_TABLE_CCK_ENTRY 32 -struct tx_power_dual_stream { - __le32 dw; -} __attribute__ ((packed)); - -struct iwl_tx_power_db { - struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; -} __attribute__ ((packed)); -#endif - -/* - * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response) - */ -struct iwl_channel_switch_cmd { - u8 band; - u8 expect_beacon; - __le16 channel; - __le32 rxon_flags; - __le32 rxon_filter_flags; - __le32 switch_time; -#if IWL == 3945 - struct iwl_power_per_rate power[IWL_MAX_RATES]; -#elif IWL == 4965 - struct iwl_tx_power_db tx_power; -#endif -} __attribute__ ((packed)); - -/* - * CHANNEL_SWITCH_NOTIFICATION = 0x73 (notification only, not a command) - */ -struct iwl_csa_notification { - __le16 band; - __le16 channel; - __le32 status; /* 0 - OK, 1 - fail */ -} __attribute__ ((packed)); - -/****************************************************************************** - * (2) - * Quality-of-Service (QOS) Commands & Responses: - * - *****************************************************************************/ -struct iwl_ac_qos { - __le16 cw_min; - __le16 cw_max; - u8 aifsn; - u8 reserved1; - __le16 edca_txop; -} __attribute__ ((packed)); - -/* QoS flags defines */ -#define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) -#define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) -#define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) - -/* - * TXFIFO Queue number defines - */ -/* number of Access categories (AC) (EDCA), queues 0..3 */ -#define AC_NUM 4 - -/* - * REPLY_QOS_PARAM = 0x13 (command, has simple generic response) - */ -struct iwl_qosparam_cmd { - __le32 qos_flags; - struct iwl_ac_qos ac[AC_NUM]; -} __attribute__ ((packed)); - -/****************************************************************************** - * (3) - * Add/Modify Stations Commands & Responses: - * - *****************************************************************************/ -/* - * Multi station support - */ -#define IWL_AP_ID 0 -#define IWL_MULTICAST_ID 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 IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ -#define IWL_INVALID_STATION 255 - -#if IWL == 3945 -#define STA_FLG_TX_RATE_MSK __constant_cpu_to_le32(1<<2); -#endif -#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1<<8); - -#define STA_CONTROL_MODIFY_MSK 0x01 - -/* key flags __le16*/ -#define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x7) -#define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0) -#define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x1) -#define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x2) -#define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x3) - -#define STA_KEY_FLG_KEYID_POS 8 -#define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) - -/* modify flags */ -#define STA_MODIFY_KEY_MASK 0x01 -#define STA_MODIFY_TID_DISABLE_TX 0x02 -#define STA_MODIFY_TX_RATE_MSK 0x04 -#define STA_MODIFY_ADDBA_TID_MSK 0x08 -#define STA_MODIFY_DELBA_TID_MSK 0x10 -#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) - -/* - * Antenna masks: - * bit14:15 01 B inactive, A active - * 10 B active, A inactive - * 11 Both active - */ -#define RATE_MCS_ANT_A_POS 14 -#define RATE_MCS_ANT_B_POS 15 -#define RATE_MCS_ANT_A_MSK 0x4000 -#define RATE_MCS_ANT_B_MSK 0x8000 -#define RATE_MCS_ANT_AB_MSK 0xc000 - -struct iwl_keyinfo { - __le16 key_flags; - u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ - u8 reserved1; - __le16 tkip_rx_ttak[5]; /* 10-byte unicast TKIP TTAK */ - __le16 reserved2; - u8 key[16]; /* 16-byte unicast decryption key */ -} __attribute__ ((packed)); - -struct sta_id_modify { - u8 addr[ETH_ALEN]; - __le16 reserved1; - u8 sta_id; - u8 modify_mask; - __le16 reserved2; -} __attribute__ ((packed)); - -/* - * REPLY_ADD_STA = 0x18 (command) - */ -struct iwl_addsta_cmd { - u8 mode; - u8 reserved[3]; - struct sta_id_modify sta; - struct iwl_keyinfo key; - __le32 station_flags; - __le32 station_flags_msk; - __le16 tid_disable_tx; -#if IWL == 3945 - __le16 rate_n_flags; -#else - __le16 reserved1; -#endif - u8 add_immediate_ba_tid; - u8 remove_immediate_ba_tid; - __le16 add_immediate_ba_ssn; -#if IWL == 4965 - __le32 reserved2; -#endif -} __attribute__ ((packed)); - -/* - * REPLY_ADD_STA = 0x18 (response) - */ -struct iwl_add_sta_resp { - u8 status; -} __attribute__ ((packed)); - -#define ADD_STA_SUCCESS_MSK 0x1 - -/****************************************************************************** - * (4) - * Rx Responses: - * - *****************************************************************************/ - -struct iwl_rx_frame_stats { - u8 phy_count; - u8 id; - u8 rssi; - u8 agc; - __le16 sig_avg; - __le16 noise_diff; - u8 payload[0]; -} __attribute__ ((packed)); - -struct iwl_rx_frame_hdr { - __le16 channel; - __le16 phy_flags; - u8 reserved1; - u8 rate; - __le16 len; - u8 payload[0]; -} __attribute__ ((packed)); - -#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) -#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) - -#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) -#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) -#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) -#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) -#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) - -#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) -#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) -#define RX_RES_STATUS_SEC_TYPE_WEP (0x1 << 8) -#define RX_RES_STATUS_SEC_TYPE_CCMP (0x2 << 8) -#define RX_RES_STATUS_SEC_TYPE_TKIP (0x3 << 8) - -#define RX_RES_STATUS_DECRYPT_TYPE_MSK (0x3 << 11) -#define RX_RES_STATUS_NOT_DECRYPT (0x0 << 11) -#define RX_RES_STATUS_DECRYPT_OK (0x3 << 11) -#define RX_RES_STATUS_BAD_ICV_MIC (0x1 << 11) -#define RX_RES_STATUS_BAD_KEY_TTAK (0x2 << 11) - -struct iwl_rx_frame_end { - __le32 status; - __le64 timestamp; - __le32 beacon_timestamp; -} __attribute__ ((packed)); - -/* - * REPLY_3945_RX = 0x1b (response only, not a command) - * - * NOTE: DO NOT dereference from casts to this structure - * It is provided only for calculating minimum data set size. - * The actual offsets of the hdr and end are dynamic based on - * stats.phy_count - */ -struct iwl_rx_frame { - struct iwl_rx_frame_stats stats; - struct iwl_rx_frame_hdr hdr; - struct iwl_rx_frame_end end; -} __attribute__ ((packed)); - -/* Fixed (non-configurable) rx data from phy */ -#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4) -#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70) -#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */ -#define IWL_AGC_DB_POS (7) -struct iwl4965_rx_non_cfg_phy { - __le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */ - __le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */ - u8 rssi_info[6]; /* we use even entries, 0/2/4 for A/B/C rssi */ - u8 pad[0]; -} __attribute__ ((packed)); - -/* - * REPLY_4965_RX = 0xc3 (response only, not a command) - * Used only for legacy (non 11n) frames. - */ -#define RX_RES_PHY_CNT 14 -struct iwl4965_rx_phy_res { - u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */ - u8 cfg_phy_cnt; /* configurable DSP phy data byte count */ - u8 stat_id; /* configurable DSP phy data set ID */ - u8 reserved1; - __le64 timestamp; /* TSF at on air rise */ - __le32 beacon_time_stamp; /* beacon at on-air rise */ - __le16 phy_flags; /* general phy flags: band, modulation, ... */ - __le16 channel; /* channel number */ - __le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */ - __le32 reserved2; - __le32 rate_n_flags; - __le16 byte_count; /* frame's byte-count */ - __le16 reserved3; -} __attribute__ ((packed)); - -struct iwl4965_rx_mpdu_res_start { - __le16 byte_count; - __le16 reserved; -} __attribute__ ((packed)); - - -/****************************************************************************** - * (5) - * Tx Commands & Responses: - * - *****************************************************************************/ - -/* Tx flags */ -#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) -#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) -#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) -#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) -#define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) -#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) -#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) -#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) -#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) - -/* ucode ignores BT priority for this frame */ -#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) - -/* ucode overrides sequence control */ -#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) - -/* signal that this frame is non-last MPDU */ -#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) - -/* calculate TSF in outgoing frame */ -#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) - -/* activate TX calibration. */ -#define TX_CMD_FLG_CALIB_MSK __constant_cpu_to_le32(1 << 17) - -/* signals that 2 bytes pad was inserted - after the MAC header */ -#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) - -/* HCCA-AP - disable duration overwriting. */ -#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) - -/* - * TX command security control - */ -#define TX_CMD_SEC_WEP 0x01 -#define TX_CMD_SEC_CCM 0x02 -#define TX_CMD_SEC_TKIP 0x03 -#define TX_CMD_SEC_MSK 0x03 -#define TX_CMD_SEC_SHIFT 6 -#define TX_CMD_SEC_KEY128 0x08 - -/* - * TX command Frame life time - */ - -struct iwl_dram_scratch { - u8 try_cnt; - u8 bt_kill_cnt; - __le16 reserved; -} __attribute__ ((packed)); - -/* - * REPLY_TX = 0x1c (command) - */ -struct iwl_tx_cmd { - __le16 len; - __le16 next_frame_len; - __le32 tx_flags; -#if IWL == 3945 - u8 rate; - u8 sta_id; - u8 tid_tspec; -#elif IWL == 4965 - struct iwl_dram_scratch scratch; - __le32 rate_n_flags; - u8 sta_id; -#endif - u8 sec_ctl; -#if IWL == 4965 - u8 initial_rate_index; - u8 reserved; -#endif - u8 key[16]; -#if IWL == 3945 - union { - u8 byte[8]; - __le16 word[4]; - __le32 dw[2]; - } tkip_mic; - __le32 next_frame_info; -#elif IWL == 4965 - __le16 next_frame_flags; - __le16 reserved2; -#endif - union { - __le32 life_time; - __le32 attempt; - } stop_time; -#if IWL == 3945 - u8 supp_rates[2]; -#elif IWL == 4965 - __le32 dram_lsb_ptr; - u8 dram_msb_ptr; -#endif - u8 rts_retry_limit; /*byte 50 */ - u8 data_retry_limit; /*byte 51 */ -#if IWL == 4965 - u8 tid_tspec; -#endif - union { - __le16 pm_frame_timeout; - __le16 attempt_duration; - } timeout; - __le16 driver_txop; - u8 payload[0]; - struct ieee80211_hdr hdr[0]; -} __attribute__ ((packed)); - -/* TX command response is sent after *all* transmission attempts. - * - * NOTES: - * - * TX_STATUS_FAIL_NEXT_FRAG - * - * If the fragment flag in the MAC header for the frame being transmitted - * is set and there is insufficient time to transmit the next frame, the - * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'. - * - * TX_STATUS_FIFO_UNDERRUN - * - * Indicates the host did not provide bytes to the FIFO fast enough while - * a TX was in progress. - * - * TX_STATUS_FAIL_MGMNT_ABORT - * - * This status is only possible if the ABORT ON MGMT RX parameter was - * set to true with the TX command. - * - * If the MSB of the status parameter is set then an abort sequence is - * required. This sequence consists of the host activating the TX Abort - * control line, and then waiting for the TX Abort command response. This - * indicates that a the device is no longer in a transmit state, and that the - * command FIFO has been cleared. The host must then deactivate the TX Abort - * control line. Receiving is still allowed in this case. - */ -enum { - TX_STATUS_SUCCESS = 0x01, - TX_STATUS_DIRECT_DONE = 0x02, - TX_STATUS_FAIL_SHORT_LIMIT = 0x82, - TX_STATUS_FAIL_LONG_LIMIT = 0x83, - TX_STATUS_FAIL_FIFO_UNDERRUN = 0x84, - TX_STATUS_FAIL_MGMNT_ABORT = 0x85, - TX_STATUS_FAIL_NEXT_FRAG = 0x86, - TX_STATUS_FAIL_LIFE_EXPIRE = 0x87, - TX_STATUS_FAIL_DEST_PS = 0x88, - TX_STATUS_FAIL_ABORTED = 0x89, - TX_STATUS_FAIL_BT_RETRY = 0x8a, - TX_STATUS_FAIL_STA_INVALID = 0x8b, - TX_STATUS_FAIL_FRAG_DROPPED = 0x8c, - TX_STATUS_FAIL_TID_DISABLE = 0x8d, - TX_STATUS_FAIL_FRAME_FLUSHED = 0x8e, - TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, - TX_STATUS_FAIL_TX_LOCKED = 0x90, - TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, -}; - -#define TX_PACKET_MODE_REGULAR 0x0000 -#define TX_PACKET_MODE_BURST_SEQ 0x0100 -#define TX_PACKET_MODE_BURST_FIRST 0x0200 - -enum { - TX_POWER_PA_NOT_ACTIVE = 0x0, -}; - -enum { - TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ - TX_STATUS_DELAY_MSK = 0x00000040, - TX_STATUS_ABORT_MSK = 0x00000080, - TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ - TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ - TX_RESERVED = 0x00780000, /* bits 19:22 */ - TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ - TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ -}; - -/* ******************************* - * TX aggregation state - ******************************* */ - -enum { - AGG_TX_STATE_TRANSMITTED = 0x00, - AGG_TX_STATE_UNDERRUN_MSK = 0x01, - AGG_TX_STATE_BT_PRIO_MSK = 0x02, - AGG_TX_STATE_FEW_BYTES_MSK = 0x04, - AGG_TX_STATE_ABORT_MSK = 0x08, - AGG_TX_STATE_LAST_SENT_TTL_MSK = 0x10, - AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK = 0x20, - AGG_TX_STATE_LAST_SENT_BT_KILL_MSK = 0x40, - AGG_TX_STATE_SCD_QUERY_MSK = 0x80, - AGG_TX_STATE_TEST_BAD_CRC32_MSK = 0x100, - AGG_TX_STATE_RESPONSE_MSK = 0x1ff, - AGG_TX_STATE_DUMP_TX_MSK = 0x200, - AGG_TX_STATE_DELAY_TX_MSK = 0x400 -}; - -#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) - -#define AGG_TX_STATE_TRY_CNT_POS 12 -#define AGG_TX_STATE_TRY_CNT_MSK 0xf000 - -#define AGG_TX_STATE_SEQ_NUM_POS 16 -#define AGG_TX_STATE_SEQ_NUM_MSK 0xffff0000 - -/* - * REPLY_TX = 0x1c (response) - */ -#if IWL == 4965 -struct iwl_tx_resp { - u8 frame_count; /* 1 no aggregation, >1 aggregation */ - u8 bt_kill_count; - u8 failure_rts; - u8 failure_frame; - __le32 rate_n_flags; - __le16 wireless_media_time; - __le16 reserved; - __le32 pa_power1; - __le32 pa_power2; - __le32 status; /* TX status (for aggregation status of 1st frame) */ -} __attribute__ ((packed)); - -#elif IWL == 3945 -struct iwl_tx_resp { - u8 failure_rts; - u8 failure_frame; - u8 bt_kill_count; - u8 rate; - __le32 wireless_media_time; - __le32 status; /* TX status (for aggregation status of 1st frame) */ -} __attribute__ ((packed)); -#endif - -/* - * REPLY_COMPRESSED_BA = 0xc5 (response only, not a command) - */ -struct iwl_compressed_ba_resp { - __le32 sta_addr_lo32; - __le16 sta_addr_hi16; - __le16 reserved; - u8 sta_id; - u8 tid; - __le16 ba_seq_ctl; - __le32 ba_bitmap0; - __le32 ba_bitmap1; - __le16 scd_flow; - __le16 scd_ssn; -} __attribute__ ((packed)); - -/* - * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response) - */ -struct iwl_txpowertable_cmd { - u8 band; /* 0: 5 GHz, 1: 2.4 GHz */ - u8 reserved; - __le16 channel; -#if IWL == 3945 - struct iwl_power_per_rate power[IWL_MAX_RATES]; -#elif IWL == 4965 - struct iwl_tx_power_db tx_power; -#endif -} __attribute__ ((packed)); - -#if IWL == 3945 -struct iwl_rate_scaling_info { - __le16 rate_n_flags; - u8 try_cnt; - u8 next_rate_index; -} __attribute__ ((packed)); - -/** - * struct iwl_rate_scaling_cmd - Rate Scaling Command & Response - * - * REPLY_RATE_SCALE = 0x47 (command, has simple generic response) - * - * NOTE: The table of rates passed to the uCode via the - * RATE_SCALE command sets up the corresponding order of - * rates used for all related commands, including rate - * masks, etc. - * - * For example, if you set 9MB (PLCP 0x0f) as the first - * rate in the rate table, the bit mask for that rate - * when passed through ofdm_basic_rates on the REPLY_RXON - * command would be bit 0 (1<<0) - */ -struct iwl_rate_scaling_cmd { - u8 table_id; - u8 reserved[3]; - struct iwl_rate_scaling_info table[IWL_MAX_RATES]; -} __attribute__ ((packed)); - -#elif IWL == 4965 - -/*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */ -#define LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK (1<<0) - -#define LINK_QUAL_AC_NUM AC_NUM -#define LINK_QUAL_MAX_RETRY_NUM 16 - -#define LINK_QUAL_ANT_A_MSK (1<<0) -#define LINK_QUAL_ANT_B_MSK (1<<1) -#define LINK_QUAL_ANT_MSK (LINK_QUAL_ANT_A_MSK|LINK_QUAL_ANT_B_MSK) - -struct iwl_link_qual_general_params { - u8 flags; - u8 mimo_delimiter; - u8 single_stream_ant_msk; - u8 dual_stream_ant_msk; - u8 start_rate_index[LINK_QUAL_AC_NUM]; -} __attribute__ ((packed)); - -struct iwl_link_qual_agg_params { - __le16 agg_time_limit; - u8 agg_dis_start_th; - u8 agg_frame_cnt_limit; - __le32 reserved; -} __attribute__ ((packed)); - -/* - * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) - */ -struct iwl_link_quality_cmd { - u8 sta_id; - u8 reserved1; - __le16 control; - struct iwl_link_qual_general_params general_params; - struct iwl_link_qual_agg_params agg_params; - struct { - __le32 rate_n_flags; - } rs_table[LINK_QUAL_MAX_RETRY_NUM]; - __le32 reserved2; -} __attribute__ ((packed)); -#endif - -/* - * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) - */ -struct iwl_bt_cmd { - u8 flags; - u8 lead_time; - u8 max_kill; - u8 reserved; - __le32 kill_ack_mask; - __le32 kill_cts_mask; -} __attribute__ ((packed)); - -/****************************************************************************** - * (6) - * Spectrum Management (802.11h) Commands, Responses, Notifications: - * - *****************************************************************************/ - -/* - * Spectrum Management - */ -#define MEASUREMENT_FILTER_FLAG (RXON_FILTER_PROMISC_MSK | \ - RXON_FILTER_CTL2HOST_MSK | \ - RXON_FILTER_ACCEPT_GRP_MSK | \ - RXON_FILTER_DIS_DECRYPT_MSK | \ - RXON_FILTER_DIS_GRP_DECRYPT_MSK | \ - RXON_FILTER_ASSOC_MSK | \ - RXON_FILTER_BCON_AWARE_MSK) - -struct iwl_measure_channel { - __le32 duration; /* measurement duration in extended beacon - * format */ - u8 channel; /* channel to measure */ - u8 type; /* see enum iwl_measure_type */ - __le16 reserved; -} __attribute__ ((packed)); - -/* - * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (command) - */ -struct iwl_spectrum_cmd { - __le16 len; /* number of bytes starting from token */ - u8 token; /* token id */ - u8 id; /* measurement id -- 0 or 1 */ - u8 origin; /* 0 = TGh, 1 = other, 2 = TGk */ - u8 periodic; /* 1 = periodic */ - __le16 path_loss_timeout; - __le32 start_time; /* start time in extended beacon format */ - __le32 reserved2; - __le32 flags; /* rxon flags */ - __le32 filter_flags; /* rxon filter flags */ - __le16 channel_count; /* minimum 1, maximum 10 */ - __le16 reserved3; - struct iwl_measure_channel channels[10]; -} __attribute__ ((packed)); - -/* - * REPLY_SPECTRUM_MEASUREMENT_CMD = 0x74 (response) - */ -struct iwl_spectrum_resp { - u8 token; - u8 id; /* id of the prior command replaced, or 0xff */ - __le16 status; /* 0 - command will be handled - * 1 - cannot handle (conflicts with another - * measurement) */ -} __attribute__ ((packed)); - -enum iwl_measurement_state { - IWL_MEASUREMENT_START = 0, - IWL_MEASUREMENT_STOP = 1, -}; - -enum iwl_measurement_status { - IWL_MEASUREMENT_OK = 0, - IWL_MEASUREMENT_CONCURRENT = 1, - IWL_MEASUREMENT_CSA_CONFLICT = 2, - IWL_MEASUREMENT_TGH_CONFLICT = 3, - /* 4-5 reserved */ - IWL_MEASUREMENT_STOPPED = 6, - IWL_MEASUREMENT_TIMEOUT = 7, - IWL_MEASUREMENT_PERIODIC_FAILED = 8, -}; - -#define NUM_ELEMENTS_IN_HISTOGRAM 8 - -struct iwl_measurement_histogram { - __le32 ofdm[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 0.8usec counts */ - __le32 cck[NUM_ELEMENTS_IN_HISTOGRAM]; /* in 1usec counts */ -} __attribute__ ((packed)); - -/* clear channel availability counters */ -struct iwl_measurement_cca_counters { - __le32 ofdm; - __le32 cck; -} __attribute__ ((packed)); - -enum iwl_measure_type { - IWL_MEASURE_BASIC = (1 << 0), - IWL_MEASURE_CHANNEL_LOAD = (1 << 1), - IWL_MEASURE_HISTOGRAM_RPI = (1 << 2), - IWL_MEASURE_HISTOGRAM_NOISE = (1 << 3), - IWL_MEASURE_FRAME = (1 << 4), - /* bits 5:6 are reserved */ - IWL_MEASURE_IDLE = (1 << 7), -}; - -/* - * SPECTRUM_MEASURE_NOTIFICATION = 0x75 (notification only, not a command) - */ -struct iwl_spectrum_notification { - u8 id; /* measurement id -- 0 or 1 */ - u8 token; - u8 channel_index; /* index in measurement channel list */ - u8 state; /* 0 - start, 1 - stop */ - __le32 start_time; /* lower 32-bits of TSF */ - u8 band; /* 0 - 5.2GHz, 1 - 2.4GHz */ - u8 channel; - u8 type; /* see enum iwl_measurement_type */ - u8 reserved1; - /* NOTE: cca_ofdm, cca_cck, basic_type, and histogram are only only - * valid if applicable for measurement type requested. */ - __le32 cca_ofdm; /* cca fraction time in 40Mhz clock periods */ - __le32 cca_cck; /* cca fraction time in 44Mhz clock periods */ - __le32 cca_time; /* channel load time in usecs */ - u8 basic_type; /* 0 - bss, 1 - ofdm preamble, 2 - - * unidentified */ - u8 reserved2[3]; - struct iwl_measurement_histogram histogram; - __le32 stop_time; /* lower 32-bits of TSF */ - __le32 status; /* see iwl_measurement_status */ -} __attribute__ ((packed)); - -/****************************************************************************** - * (7) - * Power Management Commands, Responses, Notifications: - * - *****************************************************************************/ - -/** - * struct iwl_powertable_cmd - Power Table Command - * @flags: See below: - * - * POWER_TABLE_CMD = 0x77 (command, has simple generic response) - * - * PM allow: - * bit 0 - '0' Driver not allow power management - * '1' Driver allow PM (use rest of parameters) - * uCode send sleep notifications: - * bit 1 - '0' Don't send sleep notification - * '1' send sleep notification (SEND_PM_NOTIFICATION) - * Sleep over DTIM - * bit 2 - '0' PM have to walk up every DTIM - * '1' PM could sleep over DTIM till listen Interval. - * PCI power managed - * bit 3 - '0' (PCI_LINK_CTRL & 0x1) - * '1' !(PCI_LINK_CTRL & 0x1) - * Force sleep Modes - * bit 31/30- '00' use both mac/xtal sleeps - * '01' force Mac sleep - * '10' force xtal sleep - * '11' Illegal set - * - * NOTE: if sleep_interval[SLEEP_INTRVL_TABLE_SIZE-1] > DTIM period then - * ucode assume sleep over DTIM is allowed and we don't need to wakeup - * for every DTIM. - */ -#define IWL_POWER_VEC_SIZE 5 - - -#if IWL == 3945 - -#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le32(1<<0) -#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le32(1<<2) -#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le32(1<<3) -struct iwl_powertable_cmd { - __le32 flags; - __le32 rx_data_timeout; - __le32 tx_data_timeout; - __le32 sleep_interval[IWL_POWER_VEC_SIZE]; -} __attribute__((packed)); - -#elif IWL == 4965 - -#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le16(1<<0) -#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le16(1<<2) -#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1<<3) - -struct iwl_powertable_cmd { - __le16 flags; - u8 keep_alive_seconds; - u8 debug_flags; - __le32 rx_data_timeout; - __le32 tx_data_timeout; - __le32 sleep_interval[IWL_POWER_VEC_SIZE]; - __le32 keep_alive_beacons; -} __attribute__ ((packed)); -#endif - -/* - * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) - * 3945 and 4965 identical. - */ -struct iwl_sleep_notification { - u8 pm_sleep_mode; - u8 pm_wakeup_src; - __le16 reserved; - __le32 sleep_time; - __le32 tsf_low; - __le32 bcon_timer; -} __attribute__ ((packed)); - -/* Sleep states. 3945 and 4965 identical. */ -enum { - IWL_PM_NO_SLEEP = 0, - IWL_PM_SLP_MAC = 1, - IWL_PM_SLP_FULL_MAC_UNASSOCIATE = 2, - IWL_PM_SLP_FULL_MAC_CARD_STATE = 3, - IWL_PM_SLP_PHY = 4, - IWL_PM_SLP_REPENT = 5, - IWL_PM_WAKEUP_BY_TIMER = 6, - IWL_PM_WAKEUP_BY_DRIVER = 7, - IWL_PM_WAKEUP_BY_RFKILL = 8, - /* 3 reserved */ - IWL_PM_NUM_OF_MODES = 12, -}; - -/* - * REPLY_CARD_STATE_CMD = 0xa0 (command, has simple generic response) - */ -#define CARD_STATE_CMD_DISABLE 0x00 /* Put card to sleep */ -#define CARD_STATE_CMD_ENABLE 0x01 /* Wake up card */ -#define CARD_STATE_CMD_HALT 0x02 /* Power down permanently */ -struct iwl_card_state_cmd { - __le32 status; /* CARD_STATE_CMD_* request new power state */ -} __attribute__ ((packed)); - -/* - * CARD_STATE_NOTIFICATION = 0xa1 (notification only, not a command) - */ -struct iwl_card_state_notif { - __le32 flags; -} __attribute__ ((packed)); - -#define HW_CARD_DISABLED 0x01 -#define SW_CARD_DISABLED 0x02 -#define RF_CARD_DISABLED 0x04 -#define RXON_CARD_DISABLED 0x10 - -struct iwl_ct_kill_config { - __le32 reserved; - __le32 critical_temperature_M; - __le32 critical_temperature_R; -} __attribute__ ((packed)); - -/****************************************************************************** - * (8) - * Scan Commands, Responses, Notifications: - * - *****************************************************************************/ - -struct iwl_scan_channel { - /* type is defined as: - * 0:0 active (0 - passive) - * 1:4 SSID direct - * If 1 is set then corresponding SSID IE is transmitted in probe - * 5:7 reserved - */ - u8 type; - u8 channel; - struct iwl_tx_power tpc; - __le16 active_dwell; - __le16 passive_dwell; -} __attribute__ ((packed)); - -struct iwl_ssid_ie { - u8 id; - u8 len; - u8 ssid[32]; -} __attribute__ ((packed)); - -#define PROBE_OPTION_MAX 0x4 -#define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) -#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) -#define IWL_MAX_SCAN_SIZE 1024 - -/* - * REPLY_SCAN_CMD = 0x80 (command) - */ -struct iwl_scan_cmd { - __le16 len; - u8 reserved0; - u8 channel_count; - __le16 quiet_time; /* dwell only this long on quiet chnl - * (active scan) */ - __le16 quiet_plcp_th; /* quiet chnl is < this # pkts (typ. 1) */ - __le16 good_CRC_th; /* passive -> active promotion threshold */ -#if IWL == 3945 - __le16 reserved1; -#elif IWL == 4965 - __le16 rx_chain; -#endif - __le32 max_out_time; /* max usec to be out of associated (service) - * chnl */ - __le32 suspend_time; /* pause scan this long when returning to svc - * chnl. - * 3945 -- 31:24 # beacons, 19:0 additional usec, - * 4965 -- 31:22 # beacons, 21:0 additional usec. - */ - __le32 flags; - __le32 filter_flags; - - struct iwl_tx_cmd tx_cmd; - struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; - - u8 data[0]; - /* - * The channels start after the probe request payload and are of type: - * - * struct iwl_scan_channel channels[0]; - * - * NOTE: Only one band of channels can be scanned per pass. You - * can not mix 2.4GHz channels and 5.2GHz channels and must - * request a scan multiple times (not concurrently) - * - */ -} __attribute__ ((packed)); - -/* Can abort will notify by complete notification with abort status. */ -#define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) -/* complete notification statuses */ -#define ABORT_STATUS 0x2 - -/* - * REPLY_SCAN_CMD = 0x80 (response) - */ -struct iwl_scanreq_notification { - __le32 status; /* 1: okay, 2: cannot fulfill request */ -} __attribute__ ((packed)); - -/* - * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) - */ -struct iwl_scanstart_notification { - __le32 tsf_low; - __le32 tsf_high; - __le32 beacon_timer; - u8 channel; - u8 band; - u8 reserved[2]; - __le32 status; -} __attribute__ ((packed)); - -#define SCAN_OWNER_STATUS 0x1; -#define MEASURE_OWNER_STATUS 0x2; - -#define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ -/* - * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) - */ -struct iwl_scanresults_notification { - u8 channel; - u8 band; - u8 reserved[2]; - __le32 tsf_low; - __le32 tsf_high; - __le32 statistics[NUMBER_OF_STATISTICS]; -} __attribute__ ((packed)); - -/* - * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) - */ -struct iwl_scancomplete_notification { - u8 scanned_channels; - u8 status; - u8 reserved; - u8 last_channel; - __le32 tsf_low; - __le32 tsf_high; -} __attribute__ ((packed)); - - -/****************************************************************************** - * (9) - * IBSS/AP Commands and Notifications: - * - *****************************************************************************/ - -/* - * BEACON_NOTIFICATION = 0x90 (notification only, not a command) - */ -struct iwl_beacon_notif { - struct iwl_tx_resp beacon_notify_hdr; - __le32 low_tsf; - __le32 high_tsf; - __le32 ibss_mgr_status; -} __attribute__ ((packed)); - -/* - * REPLY_TX_BEACON = 0x91 (command, has simple generic response) - */ -struct iwl_tx_beacon_cmd { - struct iwl_tx_cmd tx; - __le16 tim_idx; - u8 tim_size; - u8 reserved1; - struct ieee80211_hdr frame[0]; /* beacon frame */ -} __attribute__ ((packed)); - -/****************************************************************************** - * (10) - * Statistics Commands and Notifications: - * - *****************************************************************************/ - -#define IWL_TEMP_CONVERT 260 - -#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 -#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 -#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 - -/* Used for passing to driver number of successes and failures per rate */ -struct rate_histogram { - union { - __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; - __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; - __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; - } success; - union { - __le32 a[SUP_RATE_11A_MAX_NUM_CHANNELS]; - __le32 b[SUP_RATE_11B_MAX_NUM_CHANNELS]; - __le32 g[SUP_RATE_11G_MAX_NUM_CHANNELS]; - } failed; -} __attribute__ ((packed)); - -/* statistics command response */ - -struct statistics_rx_phy { - __le32 ina_cnt; - __le32 fina_cnt; - __le32 plcp_err; - __le32 crc32_err; - __le32 overrun_err; - __le32 early_overrun_err; - __le32 crc32_good; - __le32 false_alarm_cnt; - __le32 fina_sync_err_cnt; - __le32 sfd_timeout; - __le32 fina_timeout; - __le32 unresponded_rts; - __le32 rxe_frame_limit_overrun; - __le32 sent_ack_cnt; - __le32 sent_cts_cnt; -#if IWL == 4965 - __le32 sent_ba_rsp_cnt; - __le32 dsp_self_kill; - __le32 mh_format_err; - __le32 re_acq_main_rssi_sum; - __le32 reserved3; -#endif -} __attribute__ ((packed)); - -#if IWL == 4965 -struct statistics_rx_ht_phy { - __le32 plcp_err; - __le32 overrun_err; - __le32 early_overrun_err; - __le32 crc32_good; - __le32 crc32_err; - __le32 mh_format_err; - __le32 agg_crc32_good; - __le32 agg_mpdu_cnt; - __le32 agg_cnt; - __le32 reserved2; -} __attribute__ ((packed)); -#endif - -struct statistics_rx_non_phy { - __le32 bogus_cts; /* CTS received when not expecting CTS */ - __le32 bogus_ack; /* ACK received when not expecting ACK */ - __le32 non_bssid_frames; /* number of frames with BSSID that - * doesn't belong to the STA BSSID */ - __le32 filtered_frames; /* count frames that were dumped in the - * filtering process */ - __le32 non_channel_beacons; /* beacons with our bss id but not on - * our serving channel */ -#if IWL == 4965 - __le32 channel_beacons; /* beacons with our bss id and in our - * serving channel */ - __le32 num_missed_bcon; /* number of missed beacons */ - __le32 adc_rx_saturation_time; /* count in 0.8us units the time the - * ADC was in saturation */ - __le32 ina_detection_search_time;/* total time (in 0.8us) searched - * for INA */ - __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */ - __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */ - __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */ - __le32 interference_data_flag; /* flag for interference data - * availability. 1 when data is - * available. */ - __le32 channel_load; /* counts RX Enable time */ - __le32 dsp_false_alarms; /* DSP false alarm (both OFDM - * and CCK) counter */ - __le32 beacon_rssi_a; - __le32 beacon_rssi_b; - __le32 beacon_rssi_c; - __le32 beacon_energy_a; - __le32 beacon_energy_b; - __le32 beacon_energy_c; -#endif -} __attribute__ ((packed)); - -struct statistics_rx { - struct statistics_rx_phy ofdm; - struct statistics_rx_phy cck; - struct statistics_rx_non_phy general; -#if IWL == 4965 - struct statistics_rx_ht_phy ofdm_ht; -#endif -} __attribute__ ((packed)); - -#if IWL == 4965 -struct statistics_tx_non_phy_agg { - __le32 ba_timeout; - __le32 ba_reschedule_frames; - __le32 scd_query_agg_frame_cnt; - __le32 scd_query_no_agg; - __le32 scd_query_agg; - __le32 scd_query_mismatch; - __le32 frame_not_ready; - __le32 underrun; - __le32 bt_prio_kill; - __le32 rx_ba_rsp_cnt; - __le32 reserved2; - __le32 reserved3; -} __attribute__ ((packed)); -#endif - -struct statistics_tx { - __le32 preamble_cnt; - __le32 rx_detected_cnt; - __le32 bt_prio_defer_cnt; - __le32 bt_prio_kill_cnt; - __le32 few_bytes_cnt; - __le32 cts_timeout; - __le32 ack_timeout; - __le32 expected_ack_cnt; - __le32 actual_ack_cnt; -#if IWL == 4965 - __le32 dump_msdu_cnt; - __le32 burst_abort_next_frame_mismatch_cnt; - __le32 burst_abort_missing_next_frame_cnt; - __le32 cts_timeout_collision; - __le32 ack_or_ba_timeout_collision; - struct statistics_tx_non_phy_agg agg; -#endif -} __attribute__ ((packed)); - -struct statistics_dbg { - __le32 burst_check; - __le32 burst_count; - __le32 reserved[4]; -} __attribute__ ((packed)); - -struct statistics_div { - __le32 tx_on_a; - __le32 tx_on_b; - __le32 exec_time; - __le32 probe_time; -#if IWL == 4965 - __le32 reserved1; - __le32 reserved2; -#endif -} __attribute__ ((packed)); - -struct statistics_general { - __le32 temperature; -#if IWL == 4965 - __le32 temperature_m; -#endif - struct statistics_dbg dbg; - __le32 sleep_time; - __le32 slots_out; - __le32 slots_idle; - __le32 ttl_timestamp; - struct statistics_div div; -#if IWL == 4965 - __le32 rx_enable_counter; - __le32 reserved1; - __le32 reserved2; - __le32 reserved3; -#endif -} __attribute__ ((packed)); - -/* - * REPLY_STATISTICS_CMD = 0x9c, - * 3945 and 4965 identical. - * - * This command triggers an immediate response containing uCode statistics. - * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. - * - * If the CLEAR_STATS configuration flag is set, uCode will clear its - * internal copy of the statistics (counters) after issuing the response. - * This flag does not affect STATISTICS_NOTIFICATIONs after beacons (see below). - * - * If the DISABLE_NOTIF configuration flag is set, uCode will not issue - * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag - * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. - */ -#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ -#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ -struct iwl_statistics_cmd { - __le32 configuration_flags; /* IWL_STATS_CONF_* */ -} __attribute__ ((packed)); - -/* - * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command) - * - * By default, uCode issues this notification after receiving a beacon - * while associated. To disable this behavior, set DISABLE_NOTIF flag in the - * REPLY_STATISTICS_CMD 0x9c, above. - * - * Statistics counters continue to increment beacon after beacon, but are - * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD - * 0x9c with CLEAR_STATS bit set (see above). - * - * uCode also issues this notification during scans. uCode clears statistics - * appropriately so that each notification contains statistics for only the - * one channel that has just been scanned. - */ -#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) -#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) -struct iwl_notif_statistics { - __le32 flag; - struct statistics_rx rx; - struct statistics_tx tx; - struct statistics_general general; -} __attribute__ ((packed)); - - -/* - * MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command) - */ -/* if ucode missed CONSECUTIVE_MISSED_BCONS_TH beacons in a row, - * then this notification will be sent. */ -#define CONSECUTIVE_MISSED_BCONS_TH 20 - -struct iwl_missed_beacon_notif { - __le32 consequtive_missed_beacons; - __le32 total_missed_becons; - __le32 num_expected_beacons; - __le32 num_recvd_beacons; -} __attribute__ ((packed)); - -/****************************************************************************** - * (11) - * Rx Calibration Commands: - * - *****************************************************************************/ - -#define PHY_CALIBRATE_DIFF_GAIN_CMD (7) -#define HD_TABLE_SIZE (11) - -struct iwl_sensitivity_cmd { - __le16 control; - __le16 table[HD_TABLE_SIZE]; -} __attribute__ ((packed)); - -struct iwl_calibration_cmd { - u8 opCode; - u8 flags; - __le16 reserved; - s8 diff_gain_a; - s8 diff_gain_b; - s8 diff_gain_c; - u8 reserved1; -} __attribute__ ((packed)); - -/****************************************************************************** - * (12) - * Miscellaneous Commands: - * - *****************************************************************************/ - -/* - * LEDs Command & Response - * REPLY_LEDS_CMD = 0x48 (command, has simple generic response) - * - * For each of 3 possible LEDs (Activity/Link/Tech, selected by "id" field), - * this command turns it on or off, or sets up a periodic blinking cycle. - */ -struct iwl_led_cmd { - __le32 interval; /* "interval" in uSec */ - u8 id; /* 1: Activity, 2: Link, 3: Tech */ - u8 off; /* # intervals off while blinking; - * "0", with >0 "on" value, turns LED on */ - u8 on; /* # intervals on while blinking; - * "0", regardless of "off", turns LED off */ - u8 reserved; -} __attribute__ ((packed)); - -/****************************************************************************** - * (13) - * Union of all expected notifications/responses: - * - *****************************************************************************/ - -struct iwl_rx_packet { - __le32 len; - struct iwl_cmd_header hdr; - union { - struct iwl_alive_resp alive_frame; - struct iwl_rx_frame rx_frame; - struct iwl_tx_resp tx_resp; - struct iwl_spectrum_notification spectrum_notif; - struct iwl_csa_notification csa_notif; - struct iwl_error_resp err_resp; - struct iwl_card_state_notif card_state_notif; - struct iwl_beacon_notif beacon_status; - struct iwl_add_sta_resp add_sta; - struct iwl_sleep_notification sleep_notif; - struct iwl_spectrum_resp spectrum; - struct iwl_notif_statistics stats; -#if IWL == 4965 - struct iwl_compressed_ba_resp compressed_ba; - struct iwl_missed_beacon_notif missed_beacon; -#endif - __le32 status; - u8 raw[0]; - } u; -} __attribute__ ((packed)); - -#define IWL_RX_FRAME_SIZE (4 + sizeof(struct iwl_rx_frame)) - -#endif /* __iwl_commands_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h deleted file mode 100644 index 72318d7..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ /dev/null @@ -1,152 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project. - * - * 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_debug_h__ -#define __iwl_debug_h__ - -#ifdef CONFIG_IWLWIFI_DEBUG -extern u32 iwl_debug_level; -#define IWL_DEBUG(level, fmt, args...) \ -do { if (iwl_debug_level & (level)) \ - printk(KERN_ERR DRV_NAME": %c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) - -#define IWL_DEBUG_LIMIT(level, fmt, args...) \ -do { if ((iwl_debug_level & (level)) && net_ratelimit()) \ - printk(KERN_ERR DRV_NAME": %c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0) -#else -static inline void IWL_DEBUG(int level, const char *fmt, ...) -{ -} -static inline void IWL_DEBUG_LIMIT(int level, const char *fmt, ...) -{ -} -#endif /* CONFIG_IWLWIFI_DEBUG */ - -/* - * To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define IWL_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a IWL_xxxx_DEBUG() macro definition for your - * classification, or use IWL_DEBUG(IWL_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/iwl/debug_level - * - * you simply need to add your entry to the iwl_debug_levels array. - * - * If you do not see debug_level in /proc/net/iwl then you do not have - * CONFIG_IWLWIFI_DEBUG defined in your kernel configuration - * - */ - -#define IWL_DL_INFO (1<<0) -#define IWL_DL_MAC80211 (1<<1) -#define IWL_DL_HOST_COMMAND (1<<2) -#define IWL_DL_STATE (1<<3) - -#define IWL_DL_RADIO (1<<7) -#define IWL_DL_POWER (1<<8) -#define IWL_DL_TEMP (1<<9) - -#define IWL_DL_NOTIF (1<<10) -#define IWL_DL_SCAN (1<<11) -#define IWL_DL_ASSOC (1<<12) -#define IWL_DL_DROP (1<<13) - -#define IWL_DL_TXPOWER (1<<14) - -#define IWL_DL_AP (1<<15) - -#define IWL_DL_FW (1<<16) -#define IWL_DL_RF_KILL (1<<17) -#define IWL_DL_FW_ERRORS (1<<18) - -#define IWL_DL_LED (1<<19) - -#define IWL_DL_RATE (1<<20) - -#define IWL_DL_CALIB (1<<21) -#define IWL_DL_WEP (1<<22) -#define IWL_DL_TX (1<<23) -#define IWL_DL_RX (1<<24) -#define IWL_DL_ISR (1<<25) -#define IWL_DL_HT (1<<26) -#define IWL_DL_IO (1<<27) -#define IWL_DL_11H (1<<28) - -#define IWL_DL_STATS (1<<29) -#define IWL_DL_TX_REPLY (1<<30) -#define IWL_DL_QOS (1<<31) - -#define IWL_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a) -#define IWL_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a) -#define IWL_DEBUG_INFO(f, a...) IWL_DEBUG(IWL_DL_INFO, f, ## a) - -#define IWL_DEBUG_MAC80211(f, a...) IWL_DEBUG(IWL_DL_MAC80211, f, ## a) -#define IWL_DEBUG_TEMP(f, a...) IWL_DEBUG(IWL_DL_TEMP, f, ## a) -#define IWL_DEBUG_SCAN(f, a...) IWL_DEBUG(IWL_DL_SCAN, f, ## a) -#define IWL_DEBUG_RX(f, a...) IWL_DEBUG(IWL_DL_RX, f, ## a) -#define IWL_DEBUG_TX(f, a...) IWL_DEBUG(IWL_DL_TX, f, ## a) -#define IWL_DEBUG_ISR(f, a...) IWL_DEBUG(IWL_DL_ISR, f, ## a) -#define IWL_DEBUG_LED(f, a...) IWL_DEBUG(IWL_DL_LED, f, ## a) -#define IWL_DEBUG_WEP(f, a...) IWL_DEBUG(IWL_DL_WEP, f, ## a) -#define IWL_DEBUG_HC(f, a...) IWL_DEBUG(IWL_DL_HOST_COMMAND, f, ## a) -#define IWL_DEBUG_CALIB(f, a...) IWL_DEBUG(IWL_DL_CALIB, f, ## a) -#define IWL_DEBUG_FW(f, a...) IWL_DEBUG(IWL_DL_FW, f, ## a) -#define IWL_DEBUG_RF_KILL(f, a...) IWL_DEBUG(IWL_DL_RF_KILL, f, ## a) -#define IWL_DEBUG_DROP(f, a...) IWL_DEBUG(IWL_DL_DROP, f, ## a) -#define IWL_DEBUG_DROP_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_DROP, f, ## a) -#define IWL_DEBUG_AP(f, a...) IWL_DEBUG(IWL_DL_AP, f, ## a) -#define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a) -#define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a) -#define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a) -#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a) -#define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a) -#define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) -#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \ - IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a) -#define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a) -#define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) -#define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) -#define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) -#define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) -#define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) -#define IWL_DEBUG_11H(f, a...) IWL_DEBUG(IWL_DL_11H, f, ## a) - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h deleted file mode 100644 index e473c97..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ /dev/null @@ -1,336 +0,0 @@ -/****************************************************************************** - * - * 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) 2005 - 2007 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 Geeral 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2007 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. - * - *****************************************************************************/ - -#ifndef __iwl_eeprom_h__ -#define __iwl_eeprom_h__ - -/* - * This file defines EEPROM related constants, enums, and inline functions. - * - */ - -#define IWL_EEPROM_ACCESS_TIMEOUT 5000 /* uSec */ -#define IWL_EEPROM_ACCESS_DELAY 10 /* uSec */ -/* EEPROM field values */ -#define ANTENNA_SWITCH_NORMAL 0 -#define ANTENNA_SWITCH_INVERSE 1 - -enum { - EEPROM_CHANNEL_VALID = (1 << 0), /* usable for this SKU/geo */ - EEPROM_CHANNEL_IBSS = (1 << 1), /* usable as an IBSS channel */ - /* Bit 2 Reserved */ - EEPROM_CHANNEL_ACTIVE = (1 << 3), /* active scanning allowed */ - EEPROM_CHANNEL_RADAR = (1 << 4), /* radar detection required */ - EEPROM_CHANNEL_WIDE = (1 << 5), - EEPROM_CHANNEL_NARROW = (1 << 6), - EEPROM_CHANNEL_DFS = (1 << 7), /* dynamic freq selection candidate */ -}; - -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 - -/* EEPROM field lengths */ -#define EEPROM_BOARD_PBA_NUMBER_LENGTH 11 -#define EEPROM_REGULATORY_SKU_ID_LENGTH 4 -#define EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH 14 -#define EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH 13 -#define EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH 12 -#define EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH 11 -#define EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH 6 - -#if IWL == 3945 -#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \ - EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH) -#elif IWL == 4965 -#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH 7 -#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH 11 -#define EEPROM_REGULATORY_CHANNELS_LENGTH ( \ - EEPROM_REGULATORY_BAND1_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND2_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND3_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND4_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND5_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND_24_FAT_CHANNELS_LENGTH + \ - EEPROM_REGULATORY_BAND_52_FAT_CHANNELS_LENGTH) -#endif - -#define EEPROM_REGULATORY_NUMBER_OF_BANDS 5 - -/* SKU Capabilities */ -#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE (1 << 0) -#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE (1 << 1) -#define EEPROM_SKU_CAP_OP_MODE_MRC (1 << 7) - -/* *regulatory* channel data from eeprom, one for each channel */ -struct iwl_eeprom_channel { - u8 flags; /* flags copied from EEPROM */ - s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ -} __attribute__ ((packed)); - -/* - * Mapping of a Tx power level, at factory calibration temperature, - * to a radio/DSP gain table index. - * One for each of 5 "sample" power levels in each band. - * v_det is measured at the factory, using the 3945's built-in power amplifier - * (PA) output voltage detector. This same detector is used during Tx of - * long packets in normal operation to provide feedback as to proper output - * level. - * Data copied from EEPROM. - */ -struct iwl_eeprom_txpower_sample { - u8 gain_index; /* index into power (gain) setup table ... */ - s8 power; /* ... for this pwr level for this chnl group */ - u16 v_det; /* PA output voltage */ -} __attribute__ ((packed)); - -/* - * Mappings of Tx power levels -> nominal radio/DSP gain table indexes. - * One for each channel group (a.k.a. "band") (1 for BG, 4 for A). - * Tx power setup code interpolates between the 5 "sample" power levels - * to determine the nominal setup for a requested power level. - * Data copied from EEPROM. - * DO NOT ALTER THIS STRUCTURE!!! - */ -struct iwl_eeprom_txpower_group { - struct iwl_eeprom_txpower_sample samples[5]; /* 5 power levels */ - s32 a, b, c, d, e; /* coefficients for voltage->power - * formula (signed) */ - s32 Fa, Fb, Fc, Fd, Fe; /* these modify coeffs based on - * frequency (signed) */ - s8 saturation_power; /* highest power possible by h/w in this - * band */ - u8 group_channel; /* "representative" channel # in this band */ - s16 temperature; /* h/w temperature at factory calib this band - * (signed) */ -} __attribute__ ((packed)); - -/* - * Temperature-based Tx-power compensation data, not band-specific. - * These coefficients are use to modify a/b/c/d/e coeffs based on - * difference between current temperature and factory calib temperature. - * Data copied from EEPROM. - */ -struct iwl_eeprom_temperature_corr { - u32 Ta; - u32 Tb; - u32 Tc; - u32 Td; - u32 Te; -} __attribute__ ((packed)); - -#if IWL == 4965 -#define EEPROM_TX_POWER_TX_CHAINS (2) -#define EEPROM_TX_POWER_BANDS (8) -#define EEPROM_TX_POWER_MEASUREMENTS (3) -#define EEPROM_TX_POWER_VERSION (2) -#define EEPROM_TX_POWER_VERSION_NEW (5) - -struct iwl_eeprom_calib_measure { - u8 temperature; - u8 gain_idx; - u8 actual_pow; - s8 pa_det; -} __attribute__ ((packed)); - -struct iwl_eeprom_calib_ch_info { - u8 ch_num; - struct iwl_eeprom_calib_measure measurements[EEPROM_TX_POWER_TX_CHAINS] - [EEPROM_TX_POWER_MEASUREMENTS]; -} __attribute__ ((packed)); - -struct iwl_eeprom_calib_subband_info { - u8 ch_from; - u8 ch_to; - struct iwl_eeprom_calib_ch_info ch1; - struct iwl_eeprom_calib_ch_info ch2; -} __attribute__ ((packed)); - -struct iwl_eeprom_calib_info { - u8 saturation_power24; - u8 saturation_power52; - s16 voltage; /* signed */ - struct iwl_eeprom_calib_subband_info band_info[EEPROM_TX_POWER_BANDS]; -} __attribute__ ((packed)); - -#endif - -struct iwl_eeprom { - u8 reserved0[16]; -#define EEPROM_DEVICE_ID (2*0x08) /* 2 bytes */ - u16 device_id; /* abs.ofs: 16 */ - u8 reserved1[2]; -#define EEPROM_PMC (2*0x0A) /* 2 bytes */ - u16 pmc; /* abs.ofs: 20 */ - u8 reserved2[20]; -#define EEPROM_MAC_ADDRESS (2*0x15) /* 6 bytes */ - u8 mac_address[6]; /* abs.ofs: 42 */ - u8 reserved3[58]; -#define EEPROM_BOARD_REVISION (2*0x35) /* 2 bytes */ - u16 board_revision; /* abs.ofs: 106 */ - u8 reserved4[11]; -#define EEPROM_BOARD_PBA_NUMBER (2*0x3B+1) /* 9 bytes */ - u8 board_pba_number[9]; /* abs.ofs: 119 */ - u8 reserved5[8]; -#define EEPROM_VERSION (2*0x44) /* 2 bytes */ - u16 version; /* abs.ofs: 136 */ -#define EEPROM_SKU_CAP (2*0x45) /* 1 bytes */ - u8 sku_cap; /* abs.ofs: 138 */ -#define EEPROM_LEDS_MODE (2*0x45+1) /* 1 bytes */ - u8 leds_mode; /* abs.ofs: 139 */ -#define EEPROM_OEM_MODE (2*0x46) /* 2 bytes */ - u16 oem_mode; -#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */ - u16 wowlan_mode; /* abs.ofs: 142 */ -#define EEPROM_LEDS_TIME_INTERVAL (2*0x48) /* 2 bytes */ - u16 leds_time_interval; /* abs.ofs: 144 */ -#define EEPROM_LEDS_OFF_TIME (2*0x49) /* 1 bytes */ - u8 leds_off_time; /* abs.ofs: 146 */ -#define EEPROM_LEDS_ON_TIME (2*0x49+1) /* 1 bytes */ - u8 leds_on_time; /* abs.ofs: 147 */ -#define EEPROM_ALMGOR_M_VERSION (2*0x4A) /* 1 bytes */ - u8 almgor_m_version; /* abs.ofs: 148 */ -#define EEPROM_ANTENNA_SWITCH_TYPE (2*0x4A+1) /* 1 bytes */ - u8 antenna_switch_type; /* abs.ofs: 149 */ -#if IWL == 3945 - u8 reserved6[42]; -#else - u8 reserved6[8]; -#define EEPROM_4965_BOARD_REVISION (2*0x4F) /* 2 bytes */ - u16 board_revision_4965; /* abs.ofs: 158 */ - u8 reserved7[13]; -#define EEPROM_4965_BOARD_PBA (2*0x56+1) /* 9 bytes */ - u8 board_pba_number_4965[9]; /* abs.ofs: 173 */ - u8 reserved8[10]; -#endif -#define EEPROM_REGULATORY_SKU_ID (2*0x60) /* 4 bytes */ - u8 sku_id[4]; /* abs.ofs: 192 */ -#define EEPROM_REGULATORY_BAND_1 (2*0x62) /* 2 bytes */ - u16 band_1_count; /* abs.ofs: 196 */ -#define EEPROM_REGULATORY_BAND_1_CHANNELS (2*0x63) /* 28 bytes */ - struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */ -#define EEPROM_REGULATORY_BAND_2 (2*0x71) /* 2 bytes */ - u16 band_2_count; /* abs.ofs: 226 */ -#define EEPROM_REGULATORY_BAND_2_CHANNELS (2*0x72) /* 26 bytes */ - struct iwl_eeprom_channel band_2_channels[13]; /* abs.ofs: 228 */ -#define EEPROM_REGULATORY_BAND_3 (2*0x7F) /* 2 bytes */ - u16 band_3_count; /* abs.ofs: 254 */ -#define EEPROM_REGULATORY_BAND_3_CHANNELS (2*0x80) /* 24 bytes */ - struct iwl_eeprom_channel band_3_channels[12]; /* abs.ofs: 256 */ -#define EEPROM_REGULATORY_BAND_4 (2*0x8C) /* 2 bytes */ - u16 band_4_count; /* abs.ofs: 280 */ -#define EEPROM_REGULATORY_BAND_4_CHANNELS (2*0x8D) /* 22 bytes */ - struct iwl_eeprom_channel band_4_channels[11]; /* abs.ofs: 282 */ -#define EEPROM_REGULATORY_BAND_5 (2*0x98) /* 2 bytes */ - u16 band_5_count; /* abs.ofs: 304 */ -#define EEPROM_REGULATORY_BAND_5_CHANNELS (2*0x99) /* 12 bytes */ - struct iwl_eeprom_channel band_5_channels[6]; /* abs.ofs: 306 */ - -/* From here on out the EEPROM diverges between the 4965 and the 3945 */ -#if IWL == 3945 - - u8 reserved9[194]; - -#define EEPROM_TXPOWER_CALIB_GROUP0 0x200 -#define EEPROM_TXPOWER_CALIB_GROUP1 0x240 -#define EEPROM_TXPOWER_CALIB_GROUP2 0x280 -#define EEPROM_TXPOWER_CALIB_GROUP3 0x2c0 -#define EEPROM_TXPOWER_CALIB_GROUP4 0x300 -#define IWL_NUM_TX_CALIB_GROUPS 5 - struct iwl_eeprom_txpower_group groups[IWL_NUM_TX_CALIB_GROUPS]; -/* abs.ofs: 512 */ -#define EEPROM_CALIB_TEMPERATURE_CORRECT 0x340 - struct iwl_eeprom_temperature_corr corrections; /* abs.ofs: 832 */ - u8 reserved16[172]; /* fill out to full 1024 byte block */ - -/* 4965AGN adds fat channel support */ -#elif IWL == 4965 - - u8 reserved10[2]; -#define EEPROM_REGULATORY_BAND_24_FAT_CHANNELS (2*0xA0) /* 14 bytes */ - struct iwl_eeprom_channel band_24_channels[7]; /* abs.ofs: 320 */ - u8 reserved11[2]; -#define EEPROM_REGULATORY_BAND_52_FAT_CHANNELS (2*0xA8) /* 22 bytes */ - struct iwl_eeprom_channel band_52_channels[11]; /* abs.ofs: 336 */ - u8 reserved12[6]; -#define EEPROM_CALIB_VERSION_OFFSET (2*0xB6) /* 2 bytes */ - u16 calib_version; /* abs.ofs: 364 */ - u8 reserved13[2]; -#define EEPROM_SATURATION_POWER_OFFSET (2*0xB8) /* 2 bytes */ - u16 satruation_power; /* abs.ofs: 368 */ - u8 reserved14[94]; -#define EEPROM_IWL_CALIB_TXPOWER_OFFSET (2*0xE8) /* 48 bytes */ - struct iwl_eeprom_calib_info calib_info; /* abs.ofs: 464 */ - - u8 reserved16[140]; /* fill out to full 1024 byte block */ - -#endif - -} __attribute__ ((packed)); - -#define IWL_EEPROM_IMAGE_SIZE 1024 - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-hw.h b/drivers/net/wireless/iwlwifi/iwl-hw.h deleted file mode 100644 index 1aa6fcd..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-hw.h +++ /dev/null @@ -1,537 +0,0 @@ -/****************************************************************************** - * - * 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) 2005 - 2007 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 Geeral 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2005 - 2007 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. - *****************************************************************************/ - -#ifndef __iwlwifi_hw_h__ -#define __iwlwifi_hw_h__ - -/* - * This file defines hardware constants common to 3945 and 4965. - * - * Device-specific constants are defined in iwl-3945-hw.h and iwl-4965-hw.h, - * although this file contains a few definitions for which the .c - * implementation is the same for 3945 and 4965, except for the value of - * a constant. - * - * uCode API constants are defined in iwl-commands.h. - * - * NOTE: DO NOT PUT OS IMPLEMENTATION-SPECIFIC DECLARATIONS HERE - * - * The iwl-*hw.h (and files they include) files should remain OS/driver - * implementation independent, declaring only the hardware interface. - */ - -/* uCode queue management definitions */ -#define IWL_CMD_QUEUE_NUM 4 -#define IWL_CMD_FIFO_NUM 4 -#define IWL_BACK_QUEUE_FIRST_ID 7 - -/* Tx rates */ -#define IWL_CCK_RATES 4 -#define IWL_OFDM_RATES 8 - -#if IWL == 3945 -#define IWL_HT_RATES 0 -#elif IWL == 4965 -#define IWL_HT_RATES 16 -#endif - -#define IWL_MAX_RATES (IWL_CCK_RATES+IWL_OFDM_RATES+IWL_HT_RATES) - -/* Time constants */ -#define SHORT_SLOT_TIME 9 -#define LONG_SLOT_TIME 20 - -/* RSSI to dBm */ -#if IWL == 3945 -#define IWL_RSSI_OFFSET 95 -#elif IWL == 4965 -#define IWL_RSSI_OFFSET 44 -#endif - -#include "iwl-eeprom.h" -#include "iwl-commands.h" - -#define PCI_LINK_CTRL 0x0F0 -#define PCI_POWER_SOURCE 0x0C8 -#define PCI_REG_WUM8 0x0E8 -#define PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT (0x80000000) - -/*=== CSR (control and status registers) ===*/ -#define CSR_BASE (0x000) - -#define CSR_SW_VER (CSR_BASE+0x000) -#define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ -#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ -#define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ -#define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ -#define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ -#define CSR_GPIO_IN (CSR_BASE+0x018) /* read external chip pins */ -#define CSR_RESET (CSR_BASE+0x020) /* busmaster enable, NMI, etc*/ -#define CSR_GP_CNTRL (CSR_BASE+0x024) -#define CSR_HW_REV (CSR_BASE+0x028) -#define CSR_EEPROM_REG (CSR_BASE+0x02c) -#define CSR_EEPROM_GP (CSR_BASE+0x030) -#define CSR_GP_UCODE (CSR_BASE+0x044) -#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) -#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) -#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) -#define CSR_UCODE_DRV_GP2 (CSR_BASE+0x060) -#define CSR_LED_REG (CSR_BASE+0x094) -#define CSR_DRAM_INT_TBL_CTL (CSR_BASE+0x0A0) -#define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) -#define CSR_ANA_PLL_CFG (CSR_BASE+0x20c) -#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C) - -/* HW I/F configuration */ -#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB (0x00000100) -#define CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM (0x00000200) -#define CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC (0x00000400) -#define CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE (0x00000800) -#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000) -#define CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000) -#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000) - -/* interrupt flags in INTA, set by uCode or hardware (e.g. dma), - * acknowledged (reset) by host writing "1" to flagged bits. */ -#define CSR_INT_BIT_FH_RX (1<<31) /* Rx DMA, cmd responses, FH_INT[17:16] */ -#define CSR_INT_BIT_HW_ERR (1<<29) /* DMA hardware error FH_INT[31] */ -#define CSR_INT_BIT_DNLD (1<<28) /* uCode Download */ -#define CSR_INT_BIT_FH_TX (1<<27) /* Tx DMA FH_INT[1:0] */ -#define CSR_INT_BIT_MAC_CLK_ACTV (1<<26) /* NIC controller's clock toggled on/off */ -#define CSR_INT_BIT_SW_ERR (1<<25) /* uCode error */ -#define CSR_INT_BIT_RF_KILL (1<<7) /* HW RFKILL switch GP_CNTRL[27] toggled */ -#define CSR_INT_BIT_CT_KILL (1<<6) /* Critical temp (chip too hot) rfkill */ -#define CSR_INT_BIT_SW_RX (1<<3) /* Rx, command responses, 3945 */ -#define CSR_INT_BIT_WAKEUP (1<<1) /* NIC controller waking up (pwr mgmt) */ -#define CSR_INT_BIT_ALIVE (1<<0) /* uCode interrupts once it initializes */ - -#define CSR_INI_SET_MASK (CSR_INT_BIT_FH_RX | \ - CSR_INT_BIT_HW_ERR | \ - CSR_INT_BIT_FH_TX | \ - CSR_INT_BIT_SW_ERR | \ - CSR_INT_BIT_RF_KILL | \ - CSR_INT_BIT_SW_RX | \ - CSR_INT_BIT_WAKEUP | \ - CSR_INT_BIT_ALIVE) - -/* interrupt flags in FH (flow handler) (PCI busmaster DMA) */ -#define CSR_FH_INT_BIT_ERR (1<<31) /* Error */ -#define CSR_FH_INT_BIT_HI_PRIOR (1<<30) /* High priority Rx, bypass coalescing */ -#define CSR_FH_INT_BIT_RX_CHNL2 (1<<18) /* Rx channel 2 (3945 only) */ -#define CSR_FH_INT_BIT_RX_CHNL1 (1<<17) /* Rx channel 1 */ -#define CSR_FH_INT_BIT_RX_CHNL0 (1<<16) /* Rx channel 0 */ -#define CSR_FH_INT_BIT_TX_CHNL6 (1<<6) /* Tx channel 6 (3945 only) */ -#define CSR_FH_INT_BIT_TX_CHNL1 (1<<1) /* Tx channel 1 */ -#define CSR_FH_INT_BIT_TX_CHNL0 (1<<0) /* Tx channel 0 */ - -#define CSR_FH_INT_RX_MASK (CSR_FH_INT_BIT_HI_PRIOR | \ - CSR_FH_INT_BIT_RX_CHNL2 | \ - CSR_FH_INT_BIT_RX_CHNL1 | \ - CSR_FH_INT_BIT_RX_CHNL0) - -#define CSR_FH_INT_TX_MASK (CSR_FH_INT_BIT_TX_CHNL6 | \ - CSR_FH_INT_BIT_TX_CHNL1 | \ - CSR_FH_INT_BIT_TX_CHNL0 ) - - -/* RESET */ -#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001) -#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002) -#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080) -#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100) -#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200) - -/* GP (general purpose) CONTROL */ -#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001) -#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004) -#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008) -#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) - -#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001) - -#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000) -#define CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE (0x04000000) -#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000) - - -/* EEPROM REG */ -#define CSR_EEPROM_REG_READ_VALID_MSK (0x00000001) -#define CSR_EEPROM_REG_BIT_CMD (0x00000002) - -/* EEPROM GP */ -#define CSR_EEPROM_GP_VALID_MSK (0x00000006) -#define CSR_EEPROM_GP_BAD_SIGNATURE (0x00000000) -#define CSR_EEPROM_GP_IF_OWNER_MSK (0x00000180) - -/* UCODE DRV GP */ -#define CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP (0x00000001) -#define CSR_UCODE_SW_BIT_RFKILL (0x00000002) -#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) -#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) - -/* GPIO */ -#define CSR_GPIO_IN_BIT_AUX_POWER (0x00000200) -#define CSR_GPIO_IN_VAL_VAUX_PWR_SRC (0x00000000) -#define CSR_GPIO_IN_VAL_VMAIN_PWR_SRC CSR_GPIO_IN_BIT_AUX_POWER - -/* GI Chicken Bits */ -#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) -#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) - -/* CSR_ANA_PLL_CFG */ -#define CSR_ANA_PLL_CFG_SH (0x00880300) - -#define CSR_LED_REG_TRUN_ON (0x00000078) -#define CSR_LED_REG_TRUN_OFF (0x00000038) -#define CSR_LED_BSM_CTRL_MSK (0xFFFFFFDF) - -/* DRAM_INT_TBL_CTRL */ -#define CSR_DRAM_INT_TBL_CTRL_EN (1<<31) -#define CSR_DRAM_INT_TBL_CTRL_WRAP_CHK (1<<27) - -/*=== HBUS (Host-side Bus) ===*/ -#define HBUS_BASE (0x400) - -#define HBUS_TARG_MEM_RADDR (HBUS_BASE+0x00c) -#define HBUS_TARG_MEM_WADDR (HBUS_BASE+0x010) -#define HBUS_TARG_MEM_WDAT (HBUS_BASE+0x018) -#define HBUS_TARG_MEM_RDAT (HBUS_BASE+0x01c) -#define HBUS_TARG_PRPH_WADDR (HBUS_BASE+0x044) -#define HBUS_TARG_PRPH_RADDR (HBUS_BASE+0x048) -#define HBUS_TARG_PRPH_WDAT (HBUS_BASE+0x04c) -#define HBUS_TARG_PRPH_RDAT (HBUS_BASE+0x050) -#define HBUS_TARG_WRPTR (HBUS_BASE+0x060) - -#define HBUS_TARG_MBX_C (HBUS_BASE+0x030) - - -/* SCD (Scheduler) */ -#define SCD_BASE (CSR_BASE + 0x2E00) - -#define SCD_MODE_REG (SCD_BASE + 0x000) -#define SCD_ARASTAT_REG (SCD_BASE + 0x004) -#define SCD_TXFACT_REG (SCD_BASE + 0x010) -#define SCD_TXF4MF_REG (SCD_BASE + 0x014) -#define SCD_TXF5MF_REG (SCD_BASE + 0x020) -#define SCD_SBYP_MODE_1_REG (SCD_BASE + 0x02C) -#define SCD_SBYP_MODE_2_REG (SCD_BASE + 0x030) - -/*=== FH (data Flow Handler) ===*/ -#define FH_BASE (0x800) - -#define FH_CBCC_TABLE (FH_BASE+0x140) -#define FH_TFDB_TABLE (FH_BASE+0x180) -#define FH_RCSR_TABLE (FH_BASE+0x400) -#define FH_RSSR_TABLE (FH_BASE+0x4c0) -#define FH_TCSR_TABLE (FH_BASE+0x500) -#define FH_TSSR_TABLE (FH_BASE+0x680) - -/* TFDB (Transmit Frame Buffer Descriptor) */ -#define FH_TFDB(_channel, buf) \ - (FH_TFDB_TABLE+((_channel)*2+(buf))*0x28) -#define ALM_FH_TFDB_CHNL_BUF_CTRL_REG(_channel) \ - (FH_TFDB_TABLE + 0x50 * _channel) -/* CBCC _channel is [0,2] */ -#define FH_CBCC(_channel) (FH_CBCC_TABLE+(_channel)*0x8) -#define FH_CBCC_CTRL(_channel) (FH_CBCC(_channel)+0x00) -#define FH_CBCC_BASE(_channel) (FH_CBCC(_channel)+0x04) - -/* RCSR _channel is [0,2] */ -#define FH_RCSR(_channel) (FH_RCSR_TABLE+(_channel)*0x40) -#define FH_RCSR_CONFIG(_channel) (FH_RCSR(_channel)+0x00) -#define FH_RCSR_RBD_BASE(_channel) (FH_RCSR(_channel)+0x04) -#define FH_RCSR_WPTR(_channel) (FH_RCSR(_channel)+0x20) -#define FH_RCSR_RPTR_ADDR(_channel) (FH_RCSR(_channel)+0x24) - -#if IWL == 3945 -#define FH_RSCSR_CHNL0_WPTR (FH_RCSR_WPTR(0)) -#elif IWL == 4965 -#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG) -#endif - -/* RSSR */ -#define FH_RSSR_CTRL (FH_RSSR_TABLE+0x000) -#define FH_RSSR_STATUS (FH_RSSR_TABLE+0x004) -/* TCSR */ -#define FH_TCSR(_channel) (FH_TCSR_TABLE+(_channel)*0x20) -#define FH_TCSR_CONFIG(_channel) (FH_TCSR(_channel)+0x00) -#define FH_TCSR_CREDIT(_channel) (FH_TCSR(_channel)+0x04) -#define FH_TCSR_BUFF_STTS(_channel) (FH_TCSR(_channel)+0x08) -/* TSSR */ -#define FH_TSSR_CBB_BASE (FH_TSSR_TABLE+0x000) -#define FH_TSSR_MSG_CONFIG (FH_TSSR_TABLE+0x008) -#define FH_TSSR_TX_STATUS (FH_TSSR_TABLE+0x010) -/* 18 - reserved */ - -/* card static random access memory (SRAM) for processor data and instructs */ -#define RTC_INST_LOWER_BOUND (0x000000) -#define RTC_DATA_LOWER_BOUND (0x800000) - - -/* DBM */ - -#define ALM_FH_SRVC_CHNL (6) - -#define ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE (20) -#define ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH (4) - -#define ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN (0x08000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE (0x80000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE (0x20000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 (0x01000000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST (0x00001000) - -#define ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH (0x00000000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_DRIVER (0x00000001) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE_VAL (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL (0x00000008) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD (0x00200000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT (0x00000000) - -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE (0x00000000) -#define ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE (0x80000000) - -#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID (0x00004000) - -#define ALM_FH_TCSR_CHNL_TX_BUF_STS_REG_BIT_TFDB_WPTR (0x00000001) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON (0xFF000000) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON (0x00FF0000) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B (0x00000400) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON (0x00000100) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON (0x00000080) - -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH (0x00000020) -#define ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH (0x00000005) - -#define ALM_TB_MAX_BYTES_COUNT (0xFFF0) - -#define ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) \ - ((1LU << _channel) << 24) -#define ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel) \ - ((1LU << _channel) << 16) - -#define ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(_channel) \ - (ALM_FH_TSSR_TX_STATUS_REG_BIT_BUFS_EMPTY(_channel) | \ - ALM_FH_TSSR_TX_STATUS_REG_BIT_NO_PEND_REQ(_channel)) -#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ -#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ - -#define HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED (0x00000004) - -#define TFD_QUEUE_MIN 0 -#define TFD_QUEUE_MAX 6 -#define TFD_QUEUE_SIZE_MAX (256) - -/* spectrum and channel data structures */ -#define IWL_NUM_SCAN_RATES (2) - -#define IWL_SCAN_FLAG_24GHZ (1<<0) -#define IWL_SCAN_FLAG_52GHZ (1<<1) -#define IWL_SCAN_FLAG_ACTIVE (1<<2) -#define IWL_SCAN_FLAG_DIRECT (1<<3) - -#define IWL_MAX_CMD_SIZE 1024 - -#define IWL_DEFAULT_TX_RETRY 15 -#define IWL_MAX_TX_RETRY 16 - -/*********************************************/ - -#define RFD_SIZE 4 -#define NUM_TFD_CHUNKS 4 - -#define RX_QUEUE_SIZE 256 -#define RX_QUEUE_MASK 255 -#define RX_QUEUE_SIZE_LOG 8 - -/* QoS definitions */ - -#define CW_MIN_OFDM 15 -#define CW_MAX_OFDM 1023 -#define CW_MIN_CCK 31 -#define CW_MAX_CCK 1023 - -#define QOS_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define QOS_TX2_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_OFDM ((CW_MIN_OFDM + 1) / 4 - 1) - -#define QOS_TX0_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX1_CW_MIN_CCK CW_MIN_CCK -#define QOS_TX2_CW_MIN_CCK ((CW_MIN_CCK + 1) / 2 - 1) -#define QOS_TX3_CW_MIN_CCK ((CW_MIN_CCK + 1) / 4 - 1) - -#define QOS_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define QOS_TX2_CW_MAX_OFDM CW_MIN_OFDM -#define QOS_TX3_CW_MAX_OFDM ((CW_MIN_OFDM + 1) / 2 - 1) - -#define QOS_TX0_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX1_CW_MAX_CCK CW_MAX_CCK -#define QOS_TX2_CW_MAX_CCK CW_MIN_CCK -#define QOS_TX3_CW_MAX_CCK ((CW_MIN_CCK + 1) / 2 - 1) - -#define QOS_TX0_AIFS 3 -#define QOS_TX1_AIFS 7 -#define QOS_TX2_AIFS 2 -#define QOS_TX3_AIFS 2 - -#define QOS_TX0_ACM 0 -#define QOS_TX1_ACM 0 -#define QOS_TX2_ACM 0 -#define QOS_TX3_ACM 0 - -#define QOS_TX0_TXOP_LIMIT_CCK 0 -#define QOS_TX1_TXOP_LIMIT_CCK 0 -#define QOS_TX2_TXOP_LIMIT_CCK 6016 -#define QOS_TX3_TXOP_LIMIT_CCK 3264 - -#define QOS_TX0_TXOP_LIMIT_OFDM 0 -#define QOS_TX1_TXOP_LIMIT_OFDM 0 -#define QOS_TX2_TXOP_LIMIT_OFDM 3008 -#define QOS_TX3_TXOP_LIMIT_OFDM 1504 - -#define DEF_TX0_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX1_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX2_CW_MIN_OFDM CW_MIN_OFDM -#define DEF_TX3_CW_MIN_OFDM CW_MIN_OFDM - -#define DEF_TX0_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX1_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX2_CW_MIN_CCK CW_MIN_CCK -#define DEF_TX3_CW_MIN_CCK CW_MIN_CCK - -#define DEF_TX0_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX1_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX2_CW_MAX_OFDM CW_MAX_OFDM -#define DEF_TX3_CW_MAX_OFDM CW_MAX_OFDM - -#define DEF_TX0_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX1_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX2_CW_MAX_CCK CW_MAX_CCK -#define DEF_TX3_CW_MAX_CCK CW_MAX_CCK - -#define DEF_TX0_AIFS (2) -#define DEF_TX1_AIFS (2) -#define DEF_TX2_AIFS (2) -#define DEF_TX3_AIFS (2) - -#define DEF_TX0_ACM 0 -#define DEF_TX1_ACM 0 -#define DEF_TX2_ACM 0 -#define DEF_TX3_ACM 0 - -#define DEF_TX0_TXOP_LIMIT_CCK 0 -#define DEF_TX1_TXOP_LIMIT_CCK 0 -#define DEF_TX2_TXOP_LIMIT_CCK 0 -#define DEF_TX3_TXOP_LIMIT_CCK 0 - -#define DEF_TX0_TXOP_LIMIT_OFDM 0 -#define DEF_TX1_TXOP_LIMIT_OFDM 0 -#define DEF_TX2_TXOP_LIMIT_OFDM 0 -#define DEF_TX3_TXOP_LIMIT_OFDM 0 - -#define QOS_QOS_SETS 3 -#define QOS_PARAM_SET_ACTIVE 0 -#define QOS_PARAM_SET_DEF_CCK 1 -#define QOS_PARAM_SET_DEF_OFDM 2 - -#define CTRL_QOS_NO_ACK (0x0020) -#define DCT_FLAG_EXT_QOS_ENABLED (0x10) - -#define U32_PAD(n) ((4-(n))&0x3) - -/* - * Generic queue structure - * - * Contains common data for Rx and Tx queues - */ -#define TFD_CTL_COUNT_SET(n) (n<<24) -#define TFD_CTL_COUNT_GET(ctl) ((ctl>>24) & 7) -#define TFD_CTL_PAD_SET(n) (n<<28) -#define TFD_CTL_PAD_GET(ctl) (ctl>>28) - -#define TFD_TX_CMD_SLOTS 256 -#define TFD_CMD_SLOTS 32 - -#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \ - sizeof(struct iwl_cmd_meta)) - -/* - * RX related structures and functions - */ -#define RX_FREE_BUFFERS 64 -#define RX_LOW_WATERMARK 8 - -#endif /* __iwlwifi_hw_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h deleted file mode 100644 index 8a8b96f..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ /dev/null @@ -1,470 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2007 Intel Corporation. All rights reserved. - * - * Portions of this file are derived from the ipw3945 project. - * - * 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_io_h__ -#define __iwl_io_h__ - -#include - -#include "iwl-debug.h" - -/* - * IO, register, and NIC memory access functions - * - * NOTE on naming convention and macro usage for these - * - * A single _ prefix before a an access function means that no state - * check or debug information is printed when that function is called. - * - * A double __ prefix before an access function means that state is checked - * (in the case of *restricted calls) and the current line number is printed - * in addition to any other debug output. - * - * The non-prefixed name is the #define that maps the caller into a - * #define that provides the caller's __LINE__ to the double prefix version. - * - * If you wish to call the function without any debug or state checking, - * you should use the single _ prefix version (as is used by dependent IO - * routines, for example _iwl_read_restricted calls the non-check version of - * _iwl_read32.) - * - * These declarations are *extremely* useful in quickly isolating code deltas - * which result in misconfiguring of the hardware I/O. In combination with - * git-bisect and the IO debug level you can quickly determine the specific - * commit which breaks the IO sequence to the hardware. - * - */ - -#define _iwl_write32(iwl, ofs, val) writel((val), (iwl)->hw_base + (ofs)) -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *iwl, - u32 ofs, u32 val) -{ - IWL_DEBUG_IO("write_direct32(0x%08X, 0x%08X) - %s %d\n", - (u32) (ofs), (u32) (val), f, l); - _iwl_write32(iwl, ofs, val); -} -#define iwl_write32(iwl, ofs, val) \ - __iwl_write32(__FILE__, __LINE__, iwl, ofs, val) -#else -#define iwl_write32(iwl, ofs, val) _iwl_write32(iwl, ofs, val) -#endif - -#define _iwl_read32(iwl, ofs) readl((iwl)->hw_base + (ofs)) -#ifdef CONFIG_IWLWIFI_DEBUG -static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *iwl, u32 ofs) -{ - IWL_DEBUG_IO("read_direct32(0x%08X) - %s %d\n", ofs, f, l); - return _iwl_read32(iwl, ofs); -} -#define iwl_read32(iwl, ofs) __iwl_read32(__FILE__, __LINE__, iwl, ofs) -#else -#define iwl_read32(p, o) _iwl_read32(p, o) -#endif - -static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr, - u32 bits, u32 mask, int timeout) -{ - int i = 0; - - do { - if ((_iwl_read32(priv, addr) & mask) == (bits & mask)) - return i; - mdelay(10); - i += 10; - } while (i < timeout); - - return -ETIMEDOUT; -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_poll_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 addr, - u32 bits, u32 mask, int timeout) -{ - int rc = _iwl_poll_bit(priv, addr, bits, mask, timeout); - if (unlikely(rc == -ETIMEDOUT)) - IWL_DEBUG_IO - ("poll_bit(0x%08X, 0x%08X, 0x%08X) - timedout - %s %d\n", - addr, bits, mask, f, l); - else - IWL_DEBUG_IO - ("poll_bit(0x%08X, 0x%08X, 0x%08X) = 0x%08X - %s %d\n", - addr, bits, mask, rc, f, l); - return rc; -} -#define iwl_poll_bit(iwl, addr, bits, mask, timeout) \ - __iwl_poll_bit(__FILE__, __LINE__, iwl, addr, bits, mask, timeout) -#else -#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t) -#endif - -static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask) -{ - _iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_set_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 reg, u32 mask) -{ - u32 val = _iwl_read32(priv, reg) | mask; - IWL_DEBUG_IO("set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); - _iwl_write32(priv, reg, val); -} -#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m) -#else -#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m) -#endif - -static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask) -{ - _iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_clear_bit(const char *f, u32 l, - struct iwl_priv *priv, u32 reg, u32 mask) -{ - u32 val = _iwl_read32(priv, reg) & ~mask; - IWL_DEBUG_IO("clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val); - _iwl_write32(priv, reg, val); -} -#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m) -#else -#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m) -#endif - -static inline int _iwl_grab_restricted_access(struct iwl_priv *priv) -{ - int rc; - u32 gp_ctl; - -#ifdef CONFIG_IWLWIFI_DEBUG - if (atomic_read(&priv->restrict_refcnt)) - return 0; -#endif - if (test_bit(STATUS_RF_KILL_HW, &priv->status) || - test_bit(STATUS_RF_KILL_SW, &priv->status)) { - IWL_WARNING("WARNING: Requesting MAC access during RFKILL " - "wakes up NIC\n"); - - /* 10 msec allows time for NIC to complete its data save */ - gp_ctl = _iwl_read32(priv, CSR_GP_CNTRL); - if (gp_ctl & CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY) { - IWL_DEBUG_RF_KILL("Wait for complete power-down, " - "gpctl = 0x%08x\n", gp_ctl); - mdelay(10); - } else - IWL_DEBUG_RF_KILL("power-down complete, " - "gpctl = 0x%08x\n", gp_ctl); - } - - /* this bit wakes up the NIC */ - _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - rc = _iwl_poll_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, - (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | - CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 50); - if (rc < 0) { - IWL_ERROR("MAC is in deep sleep!\n"); - return -EIO; - } - -#ifdef CONFIG_IWLWIFI_DEBUG - atomic_inc(&priv->restrict_refcnt); -#endif - return 0; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_grab_restricted_access(const char *f, u32 l, - struct iwl_priv *priv) -{ - if (atomic_read(&priv->restrict_refcnt)) - IWL_DEBUG_INFO("Grabbing access while already held at " - "line %d.\n", l); - - IWL_DEBUG_IO("grabbing restricted access - %s %d\n", f, l); - - return _iwl_grab_restricted_access(priv); -} -#define iwl_grab_restricted_access(priv) \ - __iwl_grab_restricted_access(__FILE__, __LINE__, priv) -#else -#define iwl_grab_restricted_access(priv) \ - _iwl_grab_restricted_access(priv) -#endif - -static inline void _iwl_release_restricted_access(struct iwl_priv *priv) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - if (atomic_dec_and_test(&priv->restrict_refcnt)) -#endif - _iwl_clear_bit(priv, CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_release_restricted_access(const char *f, u32 l, - struct iwl_priv *priv) -{ - if (atomic_read(&priv->restrict_refcnt) <= 0) - IWL_ERROR("Release unheld restricted access at line %d.\n", l); - - IWL_DEBUG_IO("releasing restricted access - %s %d\n", f, l); - _iwl_release_restricted_access(priv); -} -#define iwl_release_restricted_access(priv) \ - __iwl_release_restricted_access(__FILE__, __LINE__, priv) -#else -#define iwl_release_restricted_access(priv) \ - _iwl_release_restricted_access(priv) -#endif - -static inline u32 _iwl_read_restricted(struct iwl_priv *priv, u32 reg) -{ - return _iwl_read32(priv, reg); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline u32 __iwl_read_restricted(const char *f, u32 l, - struct iwl_priv *priv, u32 reg) -{ - u32 value = _iwl_read_restricted(priv, reg); - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from %s %d\n", f, l); - IWL_DEBUG_IO("read_restricted(0x%4X) = 0x%08x - %s %d \n", reg, value, - f, l); - return value; -} -#define iwl_read_restricted(priv, reg) \ - __iwl_read_restricted(__FILE__, __LINE__, priv, reg) -#else -#define iwl_read_restricted _iwl_read_restricted -#endif - -static inline void _iwl_write_restricted(struct iwl_priv *priv, - u32 reg, u32 value) -{ - _iwl_write32(priv, reg, value); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static void __iwl_write_restricted(u32 line, - struct iwl_priv *priv, u32 reg, u32 value) -{ - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from line %d\n", line); - _iwl_write_restricted(priv, reg, value); -} -#define iwl_write_restricted(priv, reg, value) \ - __iwl_write_restricted(__LINE__, priv, reg, value) -#else -#define iwl_write_restricted _iwl_write_restricted -#endif - -static inline void iwl_write_buffer_restricted(struct iwl_priv *priv, - u32 reg, u32 len, u32 *values) -{ - u32 count = sizeof(u32); - - if ((priv != NULL) && (values != NULL)) { - for (; 0 < len; len -= count, reg += count, values++) - _iwl_write_restricted(priv, reg, *values); - } -} - -static inline int _iwl_poll_restricted_bit(struct iwl_priv *priv, - u32 addr, u32 mask, int timeout) -{ - int i = 0; - - do { - if ((_iwl_read_restricted(priv, addr) & mask) == mask) - return i; - mdelay(10); - i += 10; - } while (i < timeout); - - return -ETIMEDOUT; -} - -#ifdef CONFIG_IWLWIFI_DEBUG -static inline int __iwl_poll_restricted_bit(const char *f, u32 l, - struct iwl_priv *priv, - u32 addr, u32 mask, int timeout) -{ - int rc = _iwl_poll_restricted_bit(priv, addr, mask, timeout); - - if (unlikely(rc == -ETIMEDOUT)) - IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) - " - "timedout - %s %d\n", addr, mask, f, l); - else - IWL_DEBUG_IO("poll_restricted_bit(0x%08X, 0x%08X) = 0x%08X " - "- %s %d\n", addr, mask, rc, f, l); - return rc; -} -#define iwl_poll_restricted_bit(iwl, addr, mask, timeout) \ - __iwl_poll_restricted_bit(__FILE__, __LINE__, iwl, addr, mask, timeout) -#else -#define iwl_poll_restricted_bit _iwl_poll_restricted_bit -#endif - -static inline u32 _iwl_read_restricted_reg(struct iwl_priv *priv, u32 reg) -{ - _iwl_write_restricted(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); - return _iwl_read_restricted(priv, HBUS_TARG_PRPH_RDAT); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline u32 __iwl_read_restricted_reg(u32 line, - struct iwl_priv *priv, u32 reg) -{ - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from line %d\n", line); - return _iwl_read_restricted_reg(priv, reg); -} - -#define iwl_read_restricted_reg(priv, reg) \ - __iwl_read_restricted_reg(__LINE__, priv, reg) -#else -#define iwl_read_restricted_reg _iwl_read_restricted_reg -#endif - -static inline void _iwl_write_restricted_reg(struct iwl_priv *priv, - u32 addr, u32 val) -{ - _iwl_write_restricted(priv, HBUS_TARG_PRPH_WADDR, - ((addr & 0x0000FFFF) | (3 << 24))); - _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT, val); -} -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_write_restricted_reg(u32 line, - struct iwl_priv *priv, - u32 addr, u32 val) -{ - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from line %d\n", line); - _iwl_write_restricted_reg(priv, addr, val); -} - -#define iwl_write_restricted_reg(priv, addr, val) \ - __iwl_write_restricted_reg(__LINE__, priv, addr, val); -#else -#define iwl_write_restricted_reg _iwl_write_restricted_reg -#endif - -#define _iwl_set_bits_restricted_reg(priv, reg, mask) \ - _iwl_write_restricted_reg(priv, reg, \ - (_iwl_read_restricted_reg(priv, reg) | mask)) -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_set_bits_restricted_reg(u32 line, struct iwl_priv - *priv, u32 reg, u32 mask) -{ - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from line %d\n", line); - _iwl_set_bits_restricted_reg(priv, reg, mask); -} -#define iwl_set_bits_restricted_reg(priv, reg, mask) \ - __iwl_set_bits_restricted_reg(__LINE__, priv, reg, mask) -#else -#define iwl_set_bits_restricted_reg _iwl_set_bits_restricted_reg -#endif - -#define _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \ - _iwl_write_restricted_reg( \ - priv, reg, ((_iwl_read_restricted_reg(priv, reg) & mask) | bits)) -#ifdef CONFIG_IWLWIFI_DEBUG -static inline void __iwl_set_bits_mask_restricted_reg(u32 line, - struct iwl_priv *priv, u32 reg, u32 bits, u32 mask) -{ - if (!atomic_read(&priv->restrict_refcnt)) - IWL_ERROR("Unrestricted access from line %d\n", line); - _iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask); -} - -#define iwl_set_bits_mask_restricted_reg(priv, reg, bits, mask) \ - __iwl_set_bits_mask_restricted_reg(__LINE__, priv, reg, bits, mask) -#else -#define iwl_set_bits_mask_restricted_reg _iwl_set_bits_mask_restricted_reg -#endif - -static inline void iwl_clear_bits_restricted_reg(struct iwl_priv - *priv, u32 reg, u32 mask) -{ - u32 val = _iwl_read_restricted_reg(priv, reg); - _iwl_write_restricted_reg(priv, reg, (val & ~mask)); -} - -static inline u32 iwl_read_restricted_mem(struct iwl_priv *priv, u32 addr) -{ - iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, addr); - return iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT); -} - -static inline void iwl_write_restricted_mem(struct iwl_priv *priv, u32 addr, - u32 val) -{ - iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr); - iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, val); -} - -static inline void iwl_write_restricted_mems(struct iwl_priv *priv, u32 addr, - u32 len, u32 *values) -{ - iwl_write_restricted(priv, HBUS_TARG_MEM_WADDR, addr); - for (; 0 < len; len -= sizeof(u32), values++) - iwl_write_restricted(priv, HBUS_TARG_MEM_WDAT, *values); -} - -static inline void iwl_write_restricted_regs(struct iwl_priv *priv, u32 reg, - u32 len, u8 *values) -{ - u32 reg_offset = reg; - u32 aligment = reg & 0x3; - - /* write any non-dword-aligned stuff at the beginning */ - if (len < sizeof(u32)) { - if ((aligment + len) <= sizeof(u32)) { - u8 size; - u32 value = 0; - size = len - 1; - memcpy(&value, values, len); - reg_offset = (reg_offset & 0x0000FFFF); - - _iwl_write_restricted(priv, - HBUS_TARG_PRPH_WADDR, - (reg_offset | (size << 24))); - _iwl_write_restricted(priv, HBUS_TARG_PRPH_WDAT, - value); - } - - return; - } - - /* now write all the dword-aligned stuff */ - for (; reg_offset < (reg + len); - reg_offset += sizeof(u32), values += sizeof(u32)) - _iwl_write_restricted_reg(priv, reg_offset, *((u32 *) values)); -} - -#endif diff --git a/drivers/net/wireless/iwlwifi/iwl-priv.h b/drivers/net/wireless/iwlwifi/iwl-priv.h deleted file mode 100644 index 6b490d0..0000000 --- a/drivers/net/wireless/iwlwifi/iwl-priv.h +++ /dev/null @@ -1,308 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2007 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. - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwl_priv_h__ -#define __iwl_priv_h__ - -#include - -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT - -enum { - MEASUREMENT_READY = (1 << 0), - MEASUREMENT_ACTIVE = (1 << 1), -}; - -#endif - -struct iwl_priv { - - /* ieee device used by generic ieee processing code */ - struct ieee80211_hw *hw; - struct ieee80211_channel *ieee_channels; - struct ieee80211_rate *ieee_rates; - - /* temporary frame storage list */ - struct list_head free_frames; - int frames_count; - - u8 phymode; - int alloc_rxb_skb; - - void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); - - const struct ieee80211_hw_mode *modes; - -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT - /* spectrum measurement report caching */ - struct iwl_spectrum_notification measure_report; - u8 measurement_status; -#endif - /* ucode beacon time */ - u32 ucode_beacon_time; - - /* we allocate array of iwl_channel_info for NIC's valid channels. - * Access via channel # using indirect index array */ - struct iwl_channel_info *channel_info; /* channel info array */ - u8 channel_count; /* # of channels */ - - /* each calibration channel group in the EEPROM has a derived - * clip setting for each rate. */ - const struct iwl_clip_group clip_groups[5]; - - /* thermal calibration */ - s32 temperature; /* degrees Kelvin */ - s32 last_temperature; - - /* Scan related variables */ - unsigned long last_scan_jiffies; - unsigned long scan_start; - unsigned long scan_pass_start; - unsigned long scan_start_tsf; - int scan_bands; - int one_direct_scan; - u8 direct_ssid_len; - u8 direct_ssid[IW_ESSID_MAX_SIZE]; - struct iwl_scan_cmd *scan; - u8 only_active_channel; - - /* spinlock */ - spinlock_t lock; /* protect general shared data */ - spinlock_t hcmd_lock; /* protect hcmd */ - struct mutex mutex; - - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; - - /* uCode images, save to reload in case of failure */ - struct fw_image_desc ucode_code; /* runtime inst */ - struct fw_image_desc ucode_data; /* runtime data original */ - struct fw_image_desc ucode_data_backup; /* runtime data save/restore */ - struct fw_image_desc ucode_init; /* initialization inst */ - struct fw_image_desc ucode_init_data; /* initialization data */ - struct fw_image_desc ucode_boot; /* bootstrap inst */ - - - 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; - - int error_recovering; - struct iwl_rxon_cmd recovery_rxon; - - /* 1st responses from initialize and runtime uCode images. - * 4965's initialize alive response contains some calibration data. */ - struct iwl_init_alive_resp card_alive_init; - struct iwl_alive_resp card_alive; - -#ifdef LED - /* LED related variables */ - struct iwl_activity_blink activity; - unsigned long led_packets; - int led_state; -#endif - - u16 active_rate; - u16 active_rate_basic; - - u8 call_post_assoc_from_beacon; - u8 assoc_station_added; -#if IWL == 4965 - u8 use_ant_b_for_management_frame; /* Tx antenna selection */ - /* HT variables */ - u8 is_dup; - u8 is_ht_enabled; - u8 channel_width; /* 0=20MHZ, 1=40MHZ */ - u8 current_channel_width; - u8 valid_antenna; /* Bit mask of antennas actually connected */ -#ifdef CONFIG_IWLWIFI_SENSITIVITY - struct iwl_sensitivity_data sensitivity_data; - struct iwl_chain_noise_data chain_noise_data; - u8 start_calib; - __le16 sensitivity_tbl[HD_TABLE_SIZE]; -#endif /*CONFIG_IWLWIFI_SENSITIVITY*/ - -#ifdef CONFIG_IWLWIFI_HT - struct sta_ht_info current_assoc_ht; -#endif - u8 active_rate_ht[2]; - u8 last_phy_res[100]; - - /* Rate scaling data */ - struct iwl_lq_mngr lq_mngr; -#endif - - /* Rate scaling data */ - s8 data_retry_limit; - u8 retry_rate; - - wait_queue_head_t wait_command_queue; - - int activity_timer_active; - - /* Rx and Tx DMA processing queues */ - struct iwl_rx_queue rxq; - struct iwl_tx_queue txq[IWL_MAX_NUM_QUEUES]; -#if IWL == 4965 - unsigned long txq_ctx_active_msk; - struct iwl_kw kw; /* keep warm address */ - u32 scd_base_addr; /* scheduler sram base address */ -#endif - - unsigned long status; - u32 config; - - int last_rx_rssi; /* From Rx packet statisitics */ - int last_rx_noise; /* From beacon statistics */ - - struct iwl_power_mgr power_data; - - struct iwl_notif_statistics statistics; - unsigned long last_statistics_time; - - /* context information */ - u8 essid[IW_ESSID_MAX_SIZE]; - u8 essid_len; - u16 rates_mask; - - u32 power_mode; - u32 antenna; - u8 bssid[ETH_ALEN]; - u16 rts_threshold; - u8 mac_addr[ETH_ALEN]; - - /*station table variables */ - spinlock_t sta_lock; - int num_stations; - struct iwl_station_entry stations[IWL_STATION_COUNT]; - - /* Indication if ieee80211_ops->open has been called */ - int is_open; - - u8 mac80211_registered; - int is_abg; - - u32 notif_missed_beacons; - - /* Rx'd packet timing information */ - u32 last_beacon_time; - u64 last_tsf; - - /* Duplicate packet detection */ - u16 last_seq_num; - u16 last_frag_num; - unsigned long last_packet_time; - struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; - - /* eeprom */ - struct iwl_eeprom eeprom; - - int iw_mode; - - struct sk_buff *ibss_beacon; - - /* Last Rx'd beacon timestamp */ - u32 timestamp0; - u32 timestamp1; - u16 beacon_int; - struct iwl_driver_hw_info hw_setting; - int interface_id; - - /* Current association information needed to configure the - * hardware */ - u16 assoc_id; - u16 assoc_capability; - u8 ps_mode; - -#ifdef CONFIG_IWLWIFI_QOS - struct iwl_qos_info qos_data; -#endif /*CONFIG_IWLWIFI_QOS */ - - struct workqueue_struct *workqueue; - - struct work_struct up; - struct work_struct restart; - struct work_struct calibrated_work; - struct work_struct scan_completed; - struct work_struct rx_replenish; - struct work_struct rf_kill; - struct work_struct abort_scan; - struct work_struct update_link_led; - struct work_struct auth_work; - struct work_struct report_work; - struct work_struct request_scan; - struct work_struct beacon_update; - - struct tasklet_struct irq_tasklet; - - struct delayed_work init_alive_start; - struct delayed_work alive_start; - struct delayed_work activity_timer; - struct delayed_work thermal_periodic; - struct delayed_work gather_stats; - struct delayed_work scan_check; - struct delayed_work post_associate; - -#define IWL_DEFAULT_TX_POWER 0x0F - s8 user_txpower_limit; - s8 max_channel_txpower_limit; - u32 cck_power_index_compensation; - -#ifdef CONFIG_PM - u32 pm_state[16]; -#endif - -#ifdef CONFIG_IWLWIFI_DEBUG - /* debugging info */ - u32 framecnt_to_us; - atomic_t restrict_refcnt; -#endif - -#if IWL == 4965 - struct work_struct txpower_work; -#ifdef CONFIG_IWLWIFI_SENSITIVITY - struct work_struct sensitivity_work; -#endif - struct work_struct statistics_work; - struct timer_list statistics_periodic; - -#ifdef CONFIG_IWLWIFI_HT_AGG - struct work_struct agg_work; -#endif - -#endif /* 4965 */ -}; /*iwl_priv */ - -#endif /* __iwl_priv_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index 0df4114..4ba1216 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -8,7 +8,7 @@ * Copyright(c) 2005 - 2007 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 Geeral Public License as + * 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 @@ -63,7 +63,10 @@ #ifndef __iwl_prph_h__ #define __iwl_prph_h__ - +/* + * Registers in this file are internal, not PCI bus memory mapped. + * Driver accesses these via HBUS_TARG_PRPH_* registers. + */ #define PRPH_BASE (0x00000) #define PRPH_END (0xFFFFF) @@ -226,4 +229,58 @@ #define BSM_SRAM_SIZE (1024) /* bytes */ +/* 3945 Tx scheduler registers */ +#define ALM_SCD_BASE (PRPH_BASE + 0x2E00) +#define ALM_SCD_MODE_REG (ALM_SCD_BASE + 0x000) +#define ALM_SCD_ARASTAT_REG (ALM_SCD_BASE + 0x004) +#define ALM_SCD_TXFACT_REG (ALM_SCD_BASE + 0x010) +#define ALM_SCD_TXF4MF_REG (ALM_SCD_BASE + 0x014) +#define ALM_SCD_TXF5MF_REG (ALM_SCD_BASE + 0x020) +#define ALM_SCD_SBYP_MODE_1_REG (ALM_SCD_BASE + 0x02C) +#define ALM_SCD_SBYP_MODE_2_REG (ALM_SCD_BASE + 0x030) + +/* + * 4965 Tx Scheduler registers. + * Details are documented in iwl-4965-hw.h + */ +#define KDR_SCD_BASE (PRPH_BASE + 0xa02c00) + +#define KDR_SCD_SRAM_BASE_ADDR (KDR_SCD_BASE + 0x0) +#define KDR_SCD_EMPTY_BITS (KDR_SCD_BASE + 0x4) +#define KDR_SCD_DRAM_BASE_ADDR (KDR_SCD_BASE + 0x10) +#define KDR_SCD_AIT (KDR_SCD_BASE + 0x18) +#define KDR_SCD_TXFACT (KDR_SCD_BASE + 0x1c) +#define KDR_SCD_QUEUE_WRPTR(x) (KDR_SCD_BASE + 0x24 + (x) * 4) +#define KDR_SCD_QUEUE_RDPTR(x) (KDR_SCD_BASE + 0x64 + (x) * 4) +#define KDR_SCD_SETQUEUENUM (KDR_SCD_BASE + 0xa4) +#define KDR_SCD_SET_TXSTAT_TXED (KDR_SCD_BASE + 0xa8) +#define KDR_SCD_SET_TXSTAT_DONE (KDR_SCD_BASE + 0xac) +#define KDR_SCD_SET_TXSTAT_NOT_SCHD (KDR_SCD_BASE + 0xb0) +#define KDR_SCD_DECREASE_CREDIT (KDR_SCD_BASE + 0xb4) +#define KDR_SCD_DECREASE_SCREDIT (KDR_SCD_BASE + 0xb8) +#define KDR_SCD_LOAD_CREDIT (KDR_SCD_BASE + 0xbc) +#define KDR_SCD_LOAD_SCREDIT (KDR_SCD_BASE + 0xc0) +#define KDR_SCD_BAR (KDR_SCD_BASE + 0xc4) +#define KDR_SCD_BAR_DW0 (KDR_SCD_BASE + 0xc8) +#define KDR_SCD_BAR_DW1 (KDR_SCD_BASE + 0xcc) +#define KDR_SCD_QUEUECHAIN_SEL (KDR_SCD_BASE + 0xd0) +#define KDR_SCD_QUERY_REQ (KDR_SCD_BASE + 0xd8) +#define KDR_SCD_QUERY_RES (KDR_SCD_BASE + 0xdc) +#define KDR_SCD_PENDING_FRAMES (KDR_SCD_BASE + 0xe0) +#define KDR_SCD_INTERRUPT_MASK (KDR_SCD_BASE + 0xe4) +#define KDR_SCD_INTERRUPT_THRESHOLD (KDR_SCD_BASE + 0xe8) +#define KDR_SCD_QUERY_MIN_FRAME_SIZE (KDR_SCD_BASE + 0x100) +#define KDR_SCD_QUEUE_STATUS_BITS(x) (KDR_SCD_BASE + 0x104 + (x) * 4) + +/* SP SCD */ +#define SHL_SCD_BASE (PRPH_BASE + 0xa02c00) + +#define SHL_SCD_AIT (SHL_SCD_BASE + 0x0c) +#define SHL_SCD_TXFACT (SHL_SCD_BASE + 0x10) +#define SHL_SCD_QUEUE_WRPTR(x) (SHL_SCD_BASE + 0x18 + (x) * 4) +#define SHL_SCD_QUEUE_RDPTR(x) (SHL_SCD_BASE + 0x68 + (x) * 4) +#define SHL_SCD_QUEUECHAIN_SEL (SHL_SCD_BASE + 0xe8) +#define SHL_SCD_AGGR_SEL (SHL_SCD_BASE + 0x248) +#define SHL_SCD_INTERRUPT_MASK (SHL_SCD_BASE + 0x108) + #endif /* __iwl_prph_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 4bdf237..147ee5b 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -27,16 +27,6 @@ * *****************************************************************************/ -/* - * NOTE: This file (iwl-base.c) is used to build to multiple hardware targets - * by defining IWL to either 3945 or 4965. The Makefile used when building - * the base targets will create base-3945.o and base-4965.o - * - * The eventual goal is to move as many of the #if IWL / #endif blocks out of - * this file and into the hardware specific implementation files (iwl-XXXX.c) - * and leave only the common (non #ifdef sprinkled) code in this file - */ - #include #include #include @@ -56,16 +46,16 @@ #include -#define IWL 3945 - -#include "iwlwifi.h" #include "iwl-3945.h" #include "iwl-helpers.h" -#ifdef CONFIG_IWLWIFI_DEBUG -u32 iwl_debug_level; +#ifdef CONFIG_IWL3945_DEBUG +u32 iwl3945_debug_level; #endif +static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq); + /****************************************************************************** * * module boiler plate @@ -73,13 +63,13 @@ u32 iwl_debug_level; ******************************************************************************/ /* module parameters */ -int iwl_param_disable_hw_scan; -int iwl_param_debug; -int iwl_param_disable; /* def: enable radio */ -int iwl_param_antenna; /* def: 0 = both antennas (use diversity) */ -int iwl_param_hwcrypto; /* def: using software encryption */ -int iwl_param_qos_enable = 1; -int iwl_param_queues_num = IWL_MAX_NUM_QUEUES; +static int iwl3945_param_disable_hw_scan; /* def: 0 = use 3945's h/w scan */ +static int iwl3945_param_debug; /* def: 0 = minimal debug log messages */ +static int iwl3945_param_disable; /* def: 0 = enable radio */ +static int iwl3945_param_antenna; /* def: 0 = both antennas (use diversity) */ +int iwl3945_param_hwcrypto; /* def: 0 = use software encryption */ +static int iwl3945_param_qos_enable = 1; /* def: 1 = use quality of service */ +int iwl3945_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 8 Tx queues */ /* * module name, copyright, version, etc. @@ -89,19 +79,19 @@ int iwl_param_queues_num = IWL_MAX_NUM_QUEUES; #define DRV_DESCRIPTION \ "Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux" -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL3945_DEBUG #define VD "d" #else #define VD #endif -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT #define VS "s" #else #define VS #endif -#define IWLWIFI_VERSION "1.1.17k" VD VS +#define IWLWIFI_VERSION "1.2.22k" VD VS #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" #define DRV_VERSION IWLWIFI_VERSION @@ -116,7 +106,7 @@ MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); -__le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) +static __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) { u16 fc = le16_to_cpu(hdr->frame_control); int hdr_len = ieee80211_get_hdrlen(fc); @@ -126,8 +116,8 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) return NULL; } -static const struct ieee80211_hw_mode *iwl_get_hw_mode( - struct iwl_priv *priv, int mode) +static const struct ieee80211_hw_mode *iwl3945_get_hw_mode( + struct iwl3945_priv *priv, int mode) { int i; @@ -138,7 +128,7 @@ static const struct ieee80211_hw_mode *iwl_get_hw_mode( return NULL; } -static int iwl_is_empty_essid(const char *essid, int essid_len) +static int iwl3945_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -154,13 +144,13 @@ static int iwl_is_empty_essid(const char *essid, int essid_len) return 1; } -static const char *iwl_escape_essid(const char *essid, u8 essid_len) +static const char *iwl3945_escape_essid(const char *essid, u8 essid_len) { static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; const char *s = essid; char *d = escaped; - if (iwl_is_empty_essid(essid, essid_len)) { + if (iwl3945_is_empty_essid(essid, essid_len)) { memcpy(escaped, "", sizeof("")); return escaped; } @@ -178,10 +168,10 @@ static const char *iwl_escape_essid(const char *essid, u8 essid_len) return escaped; } -static void iwl_print_hex_dump(int level, void *p, u32 len) +static void iwl3945_print_hex_dump(int level, void *p, u32 len) { -#ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_debug_level & level)) +#ifdef CONFIG_IWL3945_DEBUG + if (!(iwl3945_debug_level & level)) return; print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, @@ -194,24 +184,31 @@ static void iwl_print_hex_dump(int level, void *p, u32 len) * * Theory of operation * - * A queue is a circular buffers with 'Read' and 'Write' pointers. - * 2 empty entries always kept in the buffer to protect from overflow. + * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer + * of buffer descriptors, each of which points to one or more data buffers for + * the device to read from or fill. Driver and device exchange status of each + * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty + * entries in each circular buffer, to protect against confusing empty and full + * queue states. + * + * The device reads or writes the data in the queues via the device's several + * DMA/FIFO channels. Each queue is mapped to a single DMA channel. * * For Tx queue, there are low mark and high mark limits. If, after queuing * the packet for Tx, free space become < low mark, Tx queue stopped. When * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * - * The IWL operates with six queues, one receive queue in the device's - * sram, one transmit queue for sending commands to the device firmware, - * and four transmit queues for data. + * The 3945 operates with six queues: One receive queue, one transmit queue + * (#4) for sending commands to the device firmware, and four transmit queues + * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused. ***************************************************/ -static int iwl_queue_space(const struct iwl_queue *q) +static int iwl3945_queue_space(const struct iwl3945_queue *q) { - int s = q->last_used - q->first_empty; + int s = q->read_ptr - q->write_ptr; - if (q->last_used > q->first_empty) + if (q->read_ptr > q->write_ptr) s -= q->n_bd; if (s <= 0) @@ -223,42 +220,55 @@ static int iwl_queue_space(const struct iwl_queue *q) return s; } -/* XXX: n_bd must be power-of-two size */ -static inline int iwl_queue_inc_wrap(int index, int n_bd) +/** + * iwl3945_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl3945_queue_inc_wrap(int index, int n_bd) { return ++index & (n_bd - 1); } -/* XXX: n_bd must be power-of-two size */ -static inline int iwl_queue_dec_wrap(int index, int n_bd) +/** + * iwl3945_queue_dec_wrap - increment queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl3945_queue_dec_wrap(int index, int n_bd) { return --index & (n_bd - 1); } -static inline int x2_queue_used(const struct iwl_queue *q, int i) +static inline int x2_queue_used(const struct iwl3945_queue *q, int i) { - return q->first_empty > q->last_used ? - (i >= q->last_used && i < q->first_empty) : - !(i < q->last_used && i >= q->first_empty); + return q->write_ptr > q->read_ptr ? + (i >= q->read_ptr && i < q->write_ptr) : + !(i < q->read_ptr && i >= q->write_ptr); } -static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) +static inline u8 get_cmd_index(struct iwl3945_queue *q, u32 index, int is_huge) { + /* This is for scan command, the big buffer at end of command array */ if (is_huge) - return q->n_window; + return q->n_window; /* must be power of 2 */ + /* Otherwise, use normal size buffers */ return index & (q->n_window - 1); } -static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, +/** + * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes + */ +static int iwl3945_queue_init(struct iwl3945_priv *priv, struct iwl3945_queue *q, int count, int slots_num, u32 id) { q->n_bd = count; q->n_window = slots_num; q->id = id; - /* count must be power-of-two size, otherwise iwl_queue_inc_wrap - * and iwl_queue_dec_wrap are broken. */ + /* count must be power-of-two size, otherwise iwl3945_queue_inc_wrap + * and iwl3945_queue_dec_wrap are broken. */ BUG_ON(!is_power_of_2(count)); /* slots_num must be power-of-two size, otherwise @@ -273,27 +283,34 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, if (q->high_mark < 2) q->high_mark = 2; - q->first_empty = q->last_used = 0; + q->write_ptr = q->read_ptr = 0; return 0; } -static int iwl_tx_queue_alloc(struct iwl_priv *priv, - struct iwl_tx_queue *txq, u32 id) +/** + * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue + */ +static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq, u32 id) { struct pci_dev *dev = priv->pci_dev; + /* Driver private data, only for Tx (not command) queues, + * not shared with device. */ if (id != IWL_CMD_QUEUE_NUM) { txq->txb = kmalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, GFP_KERNEL); if (!txq->txb) { - IWL_ERROR("kmalloc for auxilary BD " + IWL_ERROR("kmalloc for auxiliary BD " "structures failed\n"); goto error; } } else txq->txb = NULL; + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ txq->bd = pci_alloc_consistent(dev, sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, &txq->q.dma_addr); @@ -316,24 +333,33 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, return -ENOMEM; } -int iwl_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq, int slots_num, u32 txq_id) +/** + * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue + */ +int iwl3945_tx_queue_init(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq, int slots_num, u32 txq_id) { struct pci_dev *dev = priv->pci_dev; int len; int rc = 0; - /* alocate command space + one big command for scan since scan - * command is very huge the system will not have two scan at the - * same time */ - len = sizeof(struct iwl_cmd) * slots_num; + /* + * Alloc buffer array for commands (Tx or other types of commands). + * For the command queue (#4), 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 data Tx queues (all other queues), no super-size command + * space is needed. + */ + len = sizeof(struct iwl3945_cmd) * slots_num; if (txq_id == IWL_CMD_QUEUE_NUM) len += IWL_MAX_SCAN_SIZE; txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); if (!txq->cmd) return -ENOMEM; - rc = iwl_tx_queue_alloc(priv, txq, txq_id); + /* Alloc driver data array and TFD circular buffer */ + rc = iwl3945_tx_queue_alloc(priv, txq, txq_id); if (rc) { pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); @@ -342,26 +368,29 @@ int iwl_tx_queue_init(struct iwl_priv *priv, txq->need_update = 0; /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ + * iwl3945_queue_inc_wrap and iwl3945_queue_dec_wrap are broken. */ BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); - iwl_hw_tx_queue_init(priv, txq); + /* Initialize queue high/low-water, head/tail indexes */ + iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue, enable DMA channel. */ + iwl3945_hw_tx_queue_init(priv, txq); return 0; } /** - * iwl_tx_queue_free - Deallocate DMA queue. + * iwl3945_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. * * Empty queue by removing and destroying all BD's. - * Free all buffers. txq itself is not freed. - * + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. */ -void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) +void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq) { - struct iwl_queue *q = &txq->q; + struct iwl3945_queue *q = &txq->q; struct pci_dev *dev = priv->pci_dev; int len; @@ -369,44 +398,47 @@ void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) return; /* first, empty all BD's */ - for (; q->first_empty != q->last_used; - q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) - iwl_hw_txq_free_tfd(priv, txq); + for (; q->write_ptr != q->read_ptr; + q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) + iwl3945_hw_txq_free_tfd(priv, txq); - len = sizeof(struct iwl_cmd) * q->n_window; + len = sizeof(struct iwl3945_cmd) * q->n_window; if (q->id == IWL_CMD_QUEUE_NUM) len += IWL_MAX_SCAN_SIZE; + /* De-alloc array of command/tx buffers */ pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); - /* free buffers belonging to queue itself */ + /* De-alloc circular buffer of TFDs */ if (txq->q.n_bd) - pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) * + pci_free_consistent(dev, sizeof(struct iwl3945_tfd_frame) * txq->q.n_bd, txq->bd, txq->q.dma_addr); + /* De-alloc array of per-TFD driver data */ if (txq->txb) { kfree(txq->txb); txq->txb = NULL; } - /* 0 fill whole structure */ + /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -const u8 BROADCAST_ADDR[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +const u8 iwl3945_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /*************** STATION TABLE MANAGEMENT **** - * - * NOTE: This needs to be overhauled to better synchronize between - * how the iwl-4965.c is using iwl_hw_find_station vs. iwl-3945.c - * - * mac80211 should also be examined to determine if sta_info is duplicating + * mac80211 should be examined to determine if sta_info is duplicating * the functionality provided here */ /**************************************************************/ -#if 0 /* temparary disable till we add real remove station */ -static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) +#if 0 /* temporary disable till we add real remove station */ +/** + * iwl3945_remove_station - Remove driver's knowledge of station. + * + * NOTE: This does not remove station from device's station table. + */ +static u8 iwl3945_remove_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap) { int index = IWL_INVALID_STATION; int i; @@ -442,7 +474,13 @@ out: return 0; } #endif -static void iwl_clear_stations_table(struct iwl_priv *priv) + +/** + * iwl3945_clear_stations_table - Clear the driver's station table + * + * NOTE: This does not clear or otherwise alter the device's station table. + */ +static void iwl3945_clear_stations_table(struct iwl3945_priv *priv) { unsigned long flags; @@ -454,12 +492,14 @@ static void iwl_clear_stations_table(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->sta_lock, flags); } - -u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) +/** + * iwl3945_add_station - Add station to station tables in driver and device + */ +u8 iwl3945_add_station(struct iwl3945_priv *priv, const u8 *addr, int is_ap, u8 flags) { int i; int index = IWL_INVALID_STATION; - struct iwl_station_entry *station; + struct iwl3945_station_entry *station; unsigned long flags_spin; DECLARE_MAC_BUF(mac); u8 rate; @@ -482,7 +522,7 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) index = i; } - /* These twh conditions has the same outcome but keep them separate + /* These two conditions has the same outcome but keep them separate since they have different meaning */ if (unlikely(index == IWL_INVALID_STATION)) { spin_unlock_irqrestore(&priv->sta_lock, flags_spin); @@ -500,30 +540,35 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) station->used = 1; priv->num_stations++; - memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); + /* Set up the REPLY_ADD_STA command to send to device */ + memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd)); memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = index; station->sta.station_flags = 0; - rate = (priv->phymode == MODE_IEEE80211A) ? IWL_RATE_6M_PLCP : - IWL_RATE_1M_PLCP | priv->hw_setting.cck_flag; + if (priv->phymode == MODE_IEEE80211A) + rate = IWL_RATE_6M_PLCP; + else + rate = IWL_RATE_1M_PLCP; /* Turn on both antennas for the station... */ station->sta.rate_n_flags = - iwl_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK); + iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK); station->current_rate.rate_n_flags = le16_to_cpu(station->sta.rate_n_flags); spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - iwl_send_add_station(priv, &station->sta, flags); + + /* Add station to device's station table */ + iwl3945_send_add_station(priv, &station->sta, flags); return index; } /*************** DRIVER STATUS FUNCTIONS *****/ -static inline int iwl_is_ready(struct iwl_priv *priv) +static inline int iwl3945_is_ready(struct iwl3945_priv *priv) { /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are * set but EXIT_PENDING is not */ @@ -532,29 +577,29 @@ static inline int iwl_is_ready(struct iwl_priv *priv) !test_bit(STATUS_EXIT_PENDING, &priv->status); } -static inline int iwl_is_alive(struct iwl_priv *priv) +static inline int iwl3945_is_alive(struct iwl3945_priv *priv) { return test_bit(STATUS_ALIVE, &priv->status); } -static inline int iwl_is_init(struct iwl_priv *priv) +static inline int iwl3945_is_init(struct iwl3945_priv *priv) { return test_bit(STATUS_INIT, &priv->status); } -static inline int iwl_is_rfkill(struct iwl_priv *priv) +static inline int iwl3945_is_rfkill(struct iwl3945_priv *priv) { return test_bit(STATUS_RF_KILL_HW, &priv->status) || test_bit(STATUS_RF_KILL_SW, &priv->status); } -static inline int iwl_is_ready_rf(struct iwl_priv *priv) +static inline int iwl3945_is_ready_rf(struct iwl3945_priv *priv) { - if (iwl_is_rfkill(priv)) + if (iwl3945_is_rfkill(priv)) return 0; - return iwl_is_ready(priv); + return iwl3945_is_ready(priv); } /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -613,7 +658,7 @@ static const char *get_cmd_string(u8 cmd) #define HOST_COMPLETE_TIMEOUT (HZ / 2) /** - * iwl_enqueue_hcmd - enqueue a uCode command + * iwl3945_enqueue_hcmd - enqueue a uCode command * @priv: device private data point * @cmd: a point to the ucode command structure * @@ -621,13 +666,13 @@ static const char *get_cmd_string(u8 cmd) * failed. On success, it turns the index (> 0) of command in the * command queue. */ -static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl3945_enqueue_hcmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; - struct iwl_queue *q = &txq->q; - struct iwl_tfd_frame *tfd; + struct iwl3945_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl3945_queue *q = &txq->q; + struct iwl3945_tfd_frame *tfd; u32 *control_flags; - struct iwl_cmd *out_cmd; + struct iwl3945_cmd *out_cmd; u32 idx; u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); dma_addr_t phys_addr; @@ -642,19 +687,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); - if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { + if (iwl3945_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; } spin_lock_irqsave(&priv->hcmd_lock, flags); - tfd = &txq->bd[q->first_empty]; + tfd = &txq->bd[q->write_ptr]; memset(tfd, 0, sizeof(*tfd)); control_flags = (u32 *) tfd; - idx = get_cmd_index(q, q->first_empty, cmd->meta.flags & CMD_SIZE_HUGE); + idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); out_cmd = &txq->cmd[idx]; out_cmd->hdr.cmd = cmd->id; @@ -666,13 +711,13 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) out_cmd->hdr.flags = 0; out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | - INDEX_TO_SEQ(q->first_empty)); + INDEX_TO_SEQ(q->write_ptr)); if (out_cmd->meta.flags & CMD_SIZE_HUGE) out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + - offsetof(struct iwl_cmd, hdr); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); + offsetof(struct iwl3945_cmd, hdr); + iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); pad = U32_PAD(cmd->len); count = TFD_CTL_COUNT_GET(*control_flags); @@ -682,17 +727,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) "%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->first_empty, idx, IWL_CMD_QUEUE_NUM); + fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); txq->need_update = 1; - q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd); - ret = iwl_tx_queue_update_write_ptr(priv, txq); + + /* Increment and update queue's write index */ + q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); + ret = iwl3945_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->hcmd_lock, flags); return ret ? ret : idx; } -int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl3945_send_cmd_async(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) { int ret; @@ -707,16 +754,16 @@ int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EBUSY; - ret = iwl_enqueue_hcmd(priv, cmd); + ret = iwl3945_enqueue_hcmd(priv, cmd); if (ret < 0) { - IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n", + IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; } return 0; } -int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) { int cmd_idx; int ret; @@ -738,10 +785,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (cmd->meta.flags & CMD_WANT_SKB) cmd->meta.source = &cmd->meta; - cmd_idx = iwl_enqueue_hcmd(priv, cmd); + cmd_idx = iwl3945_enqueue_hcmd(priv, cmd); if (cmd_idx < 0) { ret = cmd_idx; - IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n", + IWL_ERROR("Error sending %s: iwl3945_enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); goto out; } @@ -785,7 +832,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) cancel: if (cmd->meta.flags & CMD_WANT_SKB) { - struct iwl_cmd *qcmd; + struct iwl3945_cmd *qcmd; /* Cancel the CMD_WANT_SKB flag for the cmd in the * TX cmd queue. Otherwise in case the cmd comes @@ -804,47 +851,43 @@ out: return ret; } -int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +int iwl3945_send_cmd(struct iwl3945_priv *priv, struct iwl3945_host_cmd *cmd) { - /* A command can not be asynchronous AND expect an SKB to be set. */ - BUG_ON((cmd->meta.flags & CMD_ASYNC) && - (cmd->meta.flags & CMD_WANT_SKB)); - if (cmd->meta.flags & CMD_ASYNC) - return iwl_send_cmd_async(priv, cmd); + return iwl3945_send_cmd_async(priv, cmd); - return iwl_send_cmd_sync(priv, cmd); + return iwl3945_send_cmd_sync(priv, cmd); } -int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) +int iwl3945_send_cmd_pdu(struct iwl3945_priv *priv, u8 id, u16 len, const void *data) { - struct iwl_host_cmd cmd = { + struct iwl3945_host_cmd cmd = { .id = id, .len = len, .data = data, }; - return iwl_send_cmd_sync(priv, &cmd); + return iwl3945_send_cmd_sync(priv, &cmd); } -static int __must_check iwl_send_cmd_u32(struct iwl_priv *priv, u8 id, u32 val) +static int __must_check iwl3945_send_cmd_u32(struct iwl3945_priv *priv, u8 id, u32 val) { - struct iwl_host_cmd cmd = { + struct iwl3945_host_cmd cmd = { .id = id, .len = sizeof(val), .data = &val, }; - return iwl_send_cmd_sync(priv, &cmd); + return iwl3945_send_cmd_sync(priv, &cmd); } -int iwl_send_statistics_request(struct iwl_priv *priv) +int iwl3945_send_statistics_request(struct iwl3945_priv *priv) { - return iwl_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0); + return iwl3945_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0); } /** - * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON + * iwl3945_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 @@ -853,9 +896,9 @@ int iwl_send_statistics_request(struct iwl_priv *priv) * NOTE: Does not commit to the hardware; it sets appropriate bit fields * in the staging RXON flag structure based on the phymode */ -static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel) +static int iwl3945_set_rxon_channel(struct iwl3945_priv *priv, u8 phymode, u16 channel) { - if (!iwl_get_channel_info(priv, phymode, channel)) { + if (!iwl3945_get_channel_info(priv, phymode, channel)) { IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", channel, phymode); return -EINVAL; @@ -879,13 +922,13 @@ static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel) } /** - * iwl_check_rxon_cmd - validate RXON structure is valid + * iwl3945_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 */ -static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon) +static int iwl3945_check_rxon_cmd(struct iwl3945_rxon_cmd *rxon) { int error = 0; int counter = 1; @@ -951,21 +994,21 @@ static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon) le16_to_cpu(rxon->channel)); if (error) { - IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n"); + IWL_ERROR("Not a valid iwl3945_rxon_assoc_cmd field values\n"); return -1; } return 0; } /** - * iwl_full_rxon_required - determine if RXON_ASSOC can be used in RXON commit - * @priv: staging_rxon is comapred to active_rxon + * iwl3945_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed + * @priv: staging_rxon is compared to active_rxon * - * If the RXON structure is changing sufficient to require a new - * tune or to clear and reset the RXON_FILTER_ASSOC_MSK then return 1 - * to indicate a new tune is required. + * If the RXON structure is changing enough to require a new tune, + * 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. */ -static int iwl_full_rxon_required(struct iwl_priv *priv) +static int iwl3945_full_rxon_required(struct iwl3945_priv *priv) { /* These items are only settable from the full RXON command */ @@ -1000,19 +1043,19 @@ static int iwl_full_rxon_required(struct iwl_priv *priv) return 0; } -static int iwl_send_rxon_assoc(struct iwl_priv *priv) +static int iwl3945_send_rxon_assoc(struct iwl3945_priv *priv) { int rc = 0; - struct iwl_rx_packet *res = NULL; - struct iwl_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { + struct iwl3945_rx_packet *res = NULL; + struct iwl3945_rxon_assoc_cmd rxon_assoc; + struct iwl3945_host_cmd cmd = { .id = REPLY_RXON_ASSOC, .len = sizeof(rxon_assoc), .meta.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 iwl3945_rxon_cmd *rxon1 = &priv->staging_rxon; + const struct iwl3945_rxon_cmd *rxon2 = &priv->active_rxon; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1028,11 +1071,11 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv) rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; rxon_assoc.reserved = 0; - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl3945_send_cmd_sync(priv, &cmd); if (rc) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n"); rc = -EIO; @@ -1045,21 +1088,21 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv) } /** - * iwl_commit_rxon - commit staging_rxon to hardware + * iwl3945_commit_rxon - commit staging_rxon to hardware * - * The RXON command in staging_rxon is commited to the hardware and + * 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. */ -static int iwl_commit_rxon(struct iwl_priv *priv) +static int iwl3945_commit_rxon(struct iwl3945_priv *priv) { /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; int rc = 0; DECLARE_MAC_BUF(mac); - if (!iwl_is_alive(priv)) + if (!iwl3945_is_alive(priv)) return -1; /* always get timestamp with Rx frame */ @@ -1070,17 +1113,17 @@ static int iwl_commit_rxon(struct iwl_priv *priv) ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); priv->staging_rxon.flags |= iwl3945_get_antenna_flags(priv); - rc = iwl_check_rxon_cmd(&priv->staging_rxon); + rc = iwl3945_check_rxon_cmd(&priv->staging_rxon); if (rc) { IWL_ERROR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; } /* If we don't need to send a full RXON, we can use - * iwl_rxon_assoc_cmd which is used to reconfigure filter + * 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 (!iwl3945_full_rxon_required(priv)) { + rc = iwl3945_send_rxon_assoc(priv); if (rc) { IWL_ERROR("Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1096,13 +1139,13 @@ static 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) && + if (iwl3945_is_associated(priv) && (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), + rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), &priv->active_rxon); /* If the mask clearing failed then we set @@ -1125,8 +1168,8 @@ static int iwl_commit_rxon(struct iwl_priv *priv) print_mac(mac, priv->staging_rxon.bssid_addr)); /* Apply the new configuration */ - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl3945_rxon_cmd), &priv->staging_rxon); if (rc) { IWL_ERROR("Error setting new configuration (%d).\n", rc); return rc; @@ -1134,18 +1177,18 @@ static int iwl_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); - iwl_clear_stations_table(priv); + iwl3945_clear_stations_table(priv); /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = iwl_hw_reg_send_txpower(priv); + rc = iwl3945_hw_reg_send_txpower(priv); if (rc) { IWL_ERROR("Error setting Tx power (%d).\n", rc); return rc; } /* Add the broadcast address so we can send broadcast frames */ - if (iwl_add_station(priv, BROADCAST_ADDR, 0, 0) == + if (iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0) == IWL_INVALID_STATION) { IWL_ERROR("Error adding BROADCAST address for transmit.\n"); return -EIO; @@ -1153,9 +1196,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) /* If we have set the ASSOC_MSK and we are in BSS mode then * add the IWL_AP_ID to the station rate table */ - if (iwl_is_associated(priv) && + if (iwl3945_is_associated(priv) && (priv->iw_mode == IEEE80211_IF_TYPE_STA)) - if (iwl_add_station(priv, priv->active_rxon.bssid_addr, 1, 0) + if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0) == IWL_INVALID_STATION) { IWL_ERROR("Error adding AP address for transmit.\n"); return -EIO; @@ -1172,9 +1215,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) return 0; } -static int iwl_send_bt_config(struct iwl_priv *priv) +static int iwl3945_send_bt_config(struct iwl3945_priv *priv) { - struct iwl_bt_cmd bt_cmd = { + struct iwl3945_bt_cmd bt_cmd = { .flags = 3, .lead_time = 0xAA, .max_kill = 1, @@ -1182,15 +1225,15 @@ static int iwl_send_bt_config(struct iwl_priv *priv) .kill_cts_mask = 0, }; - return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, - sizeof(struct iwl_bt_cmd), &bt_cmd); + return iwl3945_send_cmd_pdu(priv, REPLY_BT_CONFIG, + sizeof(struct iwl3945_bt_cmd), &bt_cmd); } -static int iwl_send_scan_abort(struct iwl_priv *priv) +static int iwl3945_send_scan_abort(struct iwl3945_priv *priv) { int rc = 0; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { + struct iwl3945_rx_packet *res; + struct iwl3945_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, .meta.flags = CMD_WANT_SKB, }; @@ -1203,13 +1246,13 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) return 0; } - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl3945_send_cmd_sync(priv, &cmd); if (rc) { clear_bit(STATUS_SCAN_ABORTING, &priv->status); return rc; } - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; if (res->u.status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be @@ -1227,8 +1270,8 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) return rc; } -static int iwl_card_state_sync_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, +static int iwl3945_card_state_sync_callback(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, struct sk_buff *skb) { return 1; @@ -1237,16 +1280,16 @@ static int iwl_card_state_sync_callback(struct iwl_priv *priv, /* * CARD_STATE_CMD * - * Use: Sets the internal card state to enable, disable, or halt + * 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. */ -static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) +static int iwl3945_send_card_state(struct iwl3945_priv *priv, u32 flags, u8 meta_flag) { - struct iwl_host_cmd cmd = { + struct iwl3945_host_cmd cmd = { .id = REPLY_CARD_STATE_CMD, .len = sizeof(u32), .data = &flags, @@ -1254,22 +1297,22 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) }; if (meta_flag & CMD_ASYNC) - cmd.meta.u.callback = iwl_card_state_sync_callback; + cmd.meta.u.callback = iwl3945_card_state_sync_callback; - return iwl_send_cmd(priv, &cmd); + return iwl3945_send_cmd(priv, &cmd); } -static int iwl_add_sta_sync_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, struct sk_buff *skb) +static int iwl3945_add_sta_sync_callback(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, struct sk_buff *skb) { - struct iwl_rx_packet *res = NULL; + struct iwl3945_rx_packet *res = NULL; if (!skb) { IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); return 1; } - res = (struct iwl_rx_packet *)skb->data; + res = (struct iwl3945_rx_packet *)skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", res->hdr.flags); @@ -1287,29 +1330,29 @@ static int iwl_add_sta_sync_callback(struct iwl_priv *priv, return 1; } -int iwl_send_add_station(struct iwl_priv *priv, - struct iwl_addsta_cmd *sta, u8 flags) +int iwl3945_send_add_station(struct iwl3945_priv *priv, + struct iwl3945_addsta_cmd *sta, u8 flags) { - struct iwl_rx_packet *res = NULL; + struct iwl3945_rx_packet *res = NULL; int rc = 0; - struct iwl_host_cmd cmd = { + struct iwl3945_host_cmd cmd = { .id = REPLY_ADD_STA, - .len = sizeof(struct iwl_addsta_cmd), + .len = sizeof(struct iwl3945_addsta_cmd), .meta.flags = flags, .data = sta, }; if (flags & CMD_ASYNC) - cmd.meta.u.callback = iwl_add_sta_sync_callback; + cmd.meta.u.callback = iwl3945_add_sta_sync_callback; else cmd.meta.flags |= CMD_WANT_SKB; - rc = iwl_send_cmd(priv, &cmd); + rc = iwl3945_send_cmd(priv, &cmd); if (rc || (flags & CMD_ASYNC)) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", res->hdr.flags); @@ -1334,7 +1377,7 @@ int iwl_send_add_station(struct iwl_priv *priv, return rc; } -static int iwl_update_sta_key_info(struct iwl_priv *priv, +static int iwl3945_update_sta_key_info(struct iwl3945_priv *priv, struct ieee80211_key_conf *keyconf, u8 sta_id) { @@ -1350,7 +1393,6 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv, break; case ALG_TKIP: case ALG_WEP: - return -EINVAL; default: return -EINVAL; } @@ -1369,28 +1411,28 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0); + iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0); return 0; } -static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) +static int iwl3945_clear_sta_key_info(struct iwl3945_priv *priv, u8 sta_id) { unsigned long flags; spin_lock_irqsave(&priv->sta_lock, flags); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo)); + memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl3945_keyinfo)); priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0); + iwl3945_send_add_station(priv, &priv->stations[sta_id].sta, 0); return 0; } -static void iwl_clear_free_frames(struct iwl_priv *priv) +static void iwl3945_clear_free_frames(struct iwl3945_priv *priv) { struct list_head *element; @@ -1400,7 +1442,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv) while (!list_empty(&priv->free_frames)) { element = priv->free_frames.next; list_del(element); - kfree(list_entry(element, struct iwl_frame, list)); + kfree(list_entry(element, struct iwl3945_frame, list)); priv->frames_count--; } @@ -1411,9 +1453,9 @@ static void iwl_clear_free_frames(struct iwl_priv *priv) } } -static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) +static struct iwl3945_frame *iwl3945_get_free_frame(struct iwl3945_priv *priv) { - struct iwl_frame *frame; + struct iwl3945_frame *frame; struct list_head *element; if (list_empty(&priv->free_frames)) { frame = kzalloc(sizeof(*frame), GFP_KERNEL); @@ -1428,21 +1470,21 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) element = priv->free_frames.next; list_del(element); - return list_entry(element, struct iwl_frame, list); + return list_entry(element, struct iwl3945_frame, list); } -static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) +static void iwl3945_free_frame(struct iwl3945_priv *priv, struct iwl3945_frame *frame) { memset(frame, 0, sizeof(*frame)); list_add(&frame->list, &priv->free_frames); } -unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, +unsigned int iwl3945_fill_beacon_frame(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr, const u8 *dest, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon || + if (!iwl3945_is_associated(priv) || !priv->ibss_beacon || ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) && (priv->iw_mode != IEEE80211_IF_TYPE_AP))) return 0; @@ -1455,37 +1497,37 @@ unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, return priv->ibss_beacon->len; } -static int iwl_rate_index_from_plcp(int plcp) +static int iwl3945_rate_index_from_plcp(int plcp) { int i = 0; for (i = 0; i < IWL_RATE_COUNT; i++) - if (iwl_rates[i].plcp == plcp) + if (iwl3945_rates[i].plcp == plcp) return i; return -1; } -static u8 iwl_rate_get_lowest_plcp(int rate_mask) +static u8 iwl3945_rate_get_lowest_plcp(int rate_mask) { u8 i; for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; - i = iwl_rates[i].next_ieee) { + i = iwl3945_rates[i].next_ieee) { if (rate_mask & (1 << i)) - return iwl_rates[i].plcp; + return iwl3945_rates[i].plcp; } return IWL_RATE_INVALID; } -static int iwl_send_beacon_cmd(struct iwl_priv *priv) +static int iwl3945_send_beacon_cmd(struct iwl3945_priv *priv) { - struct iwl_frame *frame; + struct iwl3945_frame *frame; unsigned int frame_size; int rc; u8 rate; - frame = iwl_get_free_frame(priv); + frame = iwl3945_get_free_frame(priv); if (!frame) { IWL_ERROR("Could not obtain free frame buffer for beacon " @@ -1494,22 +1536,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) } if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) { - rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & + rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xFF0); if (rate == IWL_INVALID_RATE) rate = IWL_RATE_6M_PLCP; } else { - rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & 0xF); + rate = iwl3945_rate_get_lowest_plcp(priv->active_rate_basic & 0xF); if (rate == IWL_INVALID_RATE) rate = IWL_RATE_1M_PLCP; } - frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate); + frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, + rc = iwl3945_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, &frame->u.cmd[0]); - iwl_free_frame(priv, frame); + iwl3945_free_frame(priv, frame); return rc; } @@ -1520,22 +1562,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) * ******************************************************************************/ -static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac) +static void get_eeprom_mac(struct iwl3945_priv *priv, u8 *mac) { memcpy(mac, priv->eeprom.mac_address, 6); } /** - * iwl_eeprom_init - read EEPROM contents + * iwl3945_eeprom_init - read EEPROM contents * - * Load the EEPROM from adapter into priv->eeprom + * Load the EEPROM contents from adapter into priv->eeprom * * NOTE: This routine uses the non-debug IO access functions. */ -int iwl_eeprom_init(struct iwl_priv *priv) +int iwl3945_eeprom_init(struct iwl3945_priv *priv) { u16 *e = (u16 *)&priv->eeprom; - u32 gp = iwl_read32(priv, CSR_EEPROM_GP); + u32 gp = iwl3945_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); int rc; @@ -1553,20 +1595,21 @@ int iwl_eeprom_init(struct iwl_priv *priv) return -ENOENT; } - rc = iwl_eeprom_aqcuire_semaphore(priv); + /* Make sure driver (instead of uCode) is allowed to read EEPROM */ + rc = iwl3945_eeprom_acquire_semaphore(priv); if (rc < 0) { - IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n"); + IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); return -ENOENT; } /* eeprom is an array of 16bit values */ for (addr = 0; addr < sz; addr += sizeof(u16)) { - _iwl_write32(priv, CSR_EEPROM_REG, addr << 1); - _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); + _iwl3945_write32(priv, CSR_EEPROM_REG, addr << 1); + _iwl3945_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT; i += IWL_EEPROM_ACCESS_DELAY) { - r = _iwl_read_restricted(priv, CSR_EEPROM_REG); + r = _iwl3945_read_direct32(priv, CSR_EEPROM_REG); if (r & CSR_EEPROM_REG_READ_VALID_MSK) break; udelay(IWL_EEPROM_ACCESS_DELAY); @@ -1587,22 +1630,17 @@ int iwl_eeprom_init(struct iwl_priv *priv) * Misc. internal state and helper functions * ******************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL3945_DEBUG /** - * iwl_report_frame - dump frame to syslog during debug sessions + * iwl3945_report_frame - dump frame to syslog during debug sessions * - * hack this function to show different aspects of received frames, + * You may hack this function to show different aspects of received frames, * including selective frame dumps. * group100 parameter selects whether to show 1 out of 100 good frames. - * - * TODO: ieee80211_hdr stuff is common to 3945 and 4965, so frame type - * info output is okay, but some of this stuff (e.g. iwl_rx_frame_stats) - * is 3945-specific and gives bad output for 4965. Need to split the - * functionality, keep common stuff here. */ -void iwl_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, +void iwl3945_report_frame(struct iwl3945_priv *priv, + struct iwl3945_rx_packet *pkt, struct ieee80211_hdr *header, int group100) { u32 to_us; @@ -1624,9 +1662,9 @@ void iwl_report_frame(struct iwl_priv *priv, u8 agc; u16 sig_avg; u16 noise_diff; - struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt); + struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); + struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt); u8 *data = IWL_RX_DATA(pkt); /* MAC header */ @@ -1702,11 +1740,11 @@ void iwl_report_frame(struct iwl_priv *priv, else title = "Frame"; - rate = iwl_rate_index_from_plcp(rate_sym); + rate = iwl3945_rate_index_from_plcp(rate_sym); if (rate == -1) rate = 0; else - rate = iwl_rates[rate].ieee / 2; + rate = iwl3945_rates[rate].ieee / 2; /* print frame summary. * MAC addresses show just the last byte (for brevity), @@ -1728,25 +1766,25 @@ void iwl_report_frame(struct iwl_priv *priv, } } if (print_dump) - iwl_print_hex_dump(IWL_DL_RX, data, length); + iwl3945_print_hex_dump(IWL_DL_RX, data, length); } #endif -static void iwl_unset_hw_setting(struct iwl_priv *priv) +static void iwl3945_unset_hw_setting(struct iwl3945_priv *priv) { if (priv->hw_setting.shared_virt) pci_free_consistent(priv->pci_dev, - sizeof(struct iwl_shared), + sizeof(struct iwl3945_shared), priv->hw_setting.shared_virt, priv->hw_setting.shared_phys); } /** - * iwl_supported_rate_to_ie - fill in the supported rate in IE field + * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field * * return : set the bit for each supported rate insert in ie */ -static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, +static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate, u16 basic_rate, int *left) { u16 ret_rates = 0, bit; @@ -1757,7 +1795,7 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { if (bit & supported_rate) { ret_rates |= bit; - rates[*cnt] = iwl_rates[i].ieee | + rates[*cnt] = iwl3945_rates[i].ieee | ((bit & basic_rate) ? 0x80 : 0x00); (*cnt)++; (*left)--; @@ -1771,9 +1809,9 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, } /** - * iwl_fill_probe_req - fill in all required fields and IE for probe request + * iwl3945_fill_probe_req - fill in all required fields and IE for probe request */ -static u16 iwl_fill_probe_req(struct iwl_priv *priv, +static u16 iwl3945_fill_probe_req(struct iwl3945_priv *priv, struct ieee80211_mgmt *frame, int left, int is_direct) { @@ -1789,9 +1827,9 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, len += 24; frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, BROADCAST_ADDR, ETH_ALEN); + memcpy(frame->da, iwl3945_broadcast_addr, ETH_ALEN); memcpy(frame->sa, priv->mac_addr, ETH_ALEN); - memcpy(frame->bssid, BROADCAST_ADDR, ETH_ALEN); + memcpy(frame->bssid, iwl3945_broadcast_addr, ETH_ALEN); frame->seq_ctrl = 0; /* fill in our indirect SSID IE */ @@ -1834,11 +1872,11 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; cck_rates = IWL_CCK_RATES_MASK & active_rates; - ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, + ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates, priv->active_rate_basic, &left); active_rates &= ~ret_rates; - ret_rates = iwl_supported_rate_to_ie(pos, active_rates, + ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates, priv->active_rate_basic, &left); active_rates &= ~ret_rates; @@ -1855,7 +1893,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* ... fill it in... */ *pos++ = WLAN_EID_EXT_SUPP_RATES; *pos = 0; - iwl_supported_rate_to_ie(pos, active_rates, + iwl3945_supported_rate_to_ie(pos, active_rates, priv->active_rate_basic, &left); if (*pos > 0) len += 2 + *pos; @@ -1867,16 +1905,16 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* * QoS support */ -#ifdef CONFIG_IWLWIFI_QOS -static int iwl_send_qos_params_command(struct iwl_priv *priv, - struct iwl_qosparam_cmd *qos) +#ifdef CONFIG_IWL3945_QOS +static int iwl3945_send_qos_params_command(struct iwl3945_priv *priv, + struct iwl3945_qosparam_cmd *qos) { - return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM, - sizeof(struct iwl_qosparam_cmd), qos); + return iwl3945_send_cmd_pdu(priv, REPLY_QOS_PARAM, + sizeof(struct iwl3945_qosparam_cmd), qos); } -static void iwl_reset_qos(struct iwl_priv *priv) +static void iwl3945_reset_qos(struct iwl3945_priv *priv) { u16 cw_min = 15; u16 cw_max = 1023; @@ -1963,13 +2001,10 @@ static void iwl_reset_qos(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void iwl_activate_qos(struct iwl_priv *priv, u8 force) +static void iwl3945_activate_qos(struct iwl3945_priv *priv, u8 force) { unsigned long flags; - if (priv == NULL) - return; - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -1990,16 +2025,16 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force) spin_unlock_irqrestore(&priv->lock, flags); - if (force || iwl_is_associated(priv)) { + if (force || iwl3945_is_associated(priv)) { IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n", priv->qos_data.qos_active); - iwl_send_qos_params_command(priv, + iwl3945_send_qos_params_command(priv, &(priv->qos_data.def_qos_parm)); } } -#endif /* CONFIG_IWLWIFI_QOS */ +#endif /* CONFIG_IWL3945_QOS */ /* * Power management (not Tx power!) functions */ @@ -2017,7 +2052,7 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force) /* default power management (not Tx power) table values */ /* for tim 0-10 */ -static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { +static struct iwl3945_power_vec_entry range_0[IWL_POWER_AC] = { {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0}, @@ -2027,7 +2062,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { }; /* for tim > 10 */ -static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { +static struct iwl3945_power_vec_entry range_1[IWL_POWER_AC] = { {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, @@ -2040,11 +2075,11 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} }; -int iwl_power_init_handle(struct iwl_priv *priv) +int iwl3945_power_init_handle(struct iwl3945_priv *priv) { int rc = 0, i; - struct iwl_power_mgr *pow_data; - int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC; + struct iwl3945_power_mgr *pow_data; + int size = sizeof(struct iwl3945_power_vec_entry) * IWL_POWER_AC; u16 pci_pm; IWL_DEBUG_POWER("Initialize power \n"); @@ -2063,7 +2098,7 @@ int iwl_power_init_handle(struct iwl_priv *priv) if (rc != 0) return 0; else { - struct iwl_powertable_cmd *cmd; + struct iwl3945_powertable_cmd *cmd; IWL_DEBUG_POWER("adjust power command flags\n"); @@ -2079,15 +2114,15 @@ int iwl_power_init_handle(struct iwl_priv *priv) return rc; } -static int iwl_update_power_cmd(struct iwl_priv *priv, - struct iwl_powertable_cmd *cmd, u32 mode) +static int iwl3945_update_power_cmd(struct iwl3945_priv *priv, + struct iwl3945_powertable_cmd *cmd, u32 mode) { int rc = 0, i; u8 skip; u32 max_sleep = 0; - struct iwl_power_vec_entry *range; + struct iwl3945_power_vec_entry *range; u8 period = 0; - struct iwl_power_mgr *pow_data; + struct iwl3945_power_mgr *pow_data; if (mode > IWL_POWER_INDEX_5) { IWL_DEBUG_POWER("Error invalid power mode \n"); @@ -2100,7 +2135,7 @@ static int iwl_update_power_cmd(struct iwl_priv *priv, else range = &pow_data->pwr_range_1[1]; - memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd)); + memcpy(cmd, &range[mode].cmd, sizeof(struct iwl3945_powertable_cmd)); #ifdef IWL_MAC80211_DISABLE if (priv->assoc_network != NULL) { @@ -2143,14 +2178,14 @@ static int iwl_update_power_cmd(struct iwl_priv *priv, return rc; } -static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) +static int iwl3945_send_power_mode(struct iwl3945_priv *priv, u32 mode) { - u32 final_mode = mode; + u32 uninitialized_var(final_mode); int rc; - struct iwl_powertable_cmd cmd; + struct iwl3945_powertable_cmd cmd; /* If on battery, set to 3, - * if plugged into AC power, set to CAM ("continuosly aware mode"), + * if plugged into AC power, set to CAM ("continuously aware mode"), * else user level */ switch (mode) { case IWL_POWER_BATTERY: @@ -2164,9 +2199,9 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) break; } - iwl_update_power_cmd(priv, &cmd, final_mode); + iwl3945_update_power_cmd(priv, &cmd, final_mode); - rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); + rc = iwl3945_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); if (final_mode == IWL_POWER_MODE_CAM) clear_bit(STATUS_POWER_PMI, &priv->status); @@ -2176,7 +2211,7 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) return rc; } -int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) +int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) { /* Filter incoming packets to determine if they are targeted toward * this network, discarding packets coming from ourselves */ @@ -2206,7 +2241,7 @@ int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x -const char *iwl_get_tx_fail_reason(u32 status) +static const char *iwl3945_get_tx_fail_reason(u32 status) { switch (status & TX_STATUS_MSK) { case TX_STATUS_SUCCESS: @@ -2233,11 +2268,11 @@ const char *iwl_get_tx_fail_reason(u32 status) } /** - * iwl_scan_cancel - Cancel any currently executing HW scan + * iwl3945_scan_cancel - Cancel any currently executing HW scan * * NOTE: priv->mutex is not required before calling this function */ -static int iwl_scan_cancel(struct iwl_priv *priv) +static int iwl3945_scan_cancel(struct iwl3945_priv *priv) { if (!test_bit(STATUS_SCAN_HW, &priv->status)) { clear_bit(STATUS_SCANNING, &priv->status); @@ -2260,17 +2295,17 @@ static int iwl_scan_cancel(struct iwl_priv *priv) } /** - * iwl_scan_cancel_timeout - Cancel any currently executing HW scan + * iwl3945_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 */ -static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) +static int iwl3945_scan_cancel_timeout(struct iwl3945_priv *priv, unsigned long ms) { unsigned long now = jiffies; int ret; - ret = iwl_scan_cancel(priv); + ret = iwl3945_scan_cancel(priv); if (ret && ms) { mutex_unlock(&priv->mutex); while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && @@ -2284,7 +2319,7 @@ static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) return ret; } -static void iwl_sequence_reset(struct iwl_priv *priv) +static void iwl3945_sequence_reset(struct iwl3945_priv *priv) { /* Reset ieee stats */ @@ -2295,13 +2330,13 @@ static void iwl_sequence_reset(struct iwl_priv *priv) priv->last_frag_num = -1; priv->last_packet_time = 0; - iwl_scan_cancel(priv); + iwl3945_scan_cancel(priv); } #define MAX_UCODE_BEACON_INTERVAL 1024 #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) -static __le16 iwl_adjust_beacon_interval(u16 beacon_val) +static __le16 iwl3945_adjust_beacon_interval(u16 beacon_val) { u16 new_val = 0; u16 beacon_factor = 0; @@ -2314,7 +2349,7 @@ static __le16 iwl_adjust_beacon_interval(u16 beacon_val) return cpu_to_le16(new_val); } -static void iwl_setup_rxon_timing(struct iwl_priv *priv) +static void iwl3945_setup_rxon_timing(struct iwl3945_priv *priv) { u64 interval_tm_unit; u64 tsf, result; @@ -2344,14 +2379,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); priv->rxon_timing.beacon_interval = - iwl_adjust_beacon_interval( + iwl3945_adjust_beacon_interval( le16_to_cpu(priv->rxon_timing.beacon_interval)); } priv->rxon_timing.atim_window = 0; } else { priv->rxon_timing.beacon_interval = - iwl_adjust_beacon_interval(conf->beacon_int); + iwl3945_adjust_beacon_interval(conf->beacon_int); /* TODO: we need to get atim_window from upper stack * for now we set to 0 */ priv->rxon_timing.atim_window = 0; @@ -2370,14 +2405,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) le16_to_cpu(priv->rxon_timing.atim_window)); } -static int iwl_scan_initiate(struct iwl_priv *priv) +static int iwl3945_scan_initiate(struct iwl3945_priv *priv) { if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { IWL_ERROR("APs don't scan.\n"); return 0; } - if (!iwl_is_ready_rf(priv)) { + if (!iwl3945_is_ready_rf(priv)) { IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); return -EIO; } @@ -2404,9 +2439,9 @@ static int iwl_scan_initiate(struct iwl_priv *priv) return 0; } -static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) +static int iwl3945_set_rxon_hwcrypto(struct iwl3945_priv *priv, int hw_decrypt) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl3945_rxon_cmd *rxon = &priv->staging_rxon; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -2416,7 +2451,7 @@ static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) return 0; } -static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) +static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode) { if (phymode == MODE_IEEE80211A) { priv->staging_rxon.flags &= @@ -2424,7 +2459,7 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) | RXON_FLG_CCK_MSK); priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { - /* Copied from iwl_bg_post_associate() */ + /* Copied from iwl3945_bg_post_associate() */ if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else @@ -2440,11 +2475,11 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) } /* - * initilize rxon structure with default values fromm eeprom + * initialize rxon structure with default values from eeprom */ -static void iwl_connection_init_rx_config(struct iwl_priv *priv) +static void iwl3945_connection_init_rx_config(struct iwl3945_priv *priv) { - const struct iwl_channel_info *ch_info; + const struct iwl3945_channel_info *ch_info; memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); @@ -2481,7 +2516,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif - ch_info = iwl_get_channel_info(priv, priv->phymode, + ch_info = iwl3945_get_channel_info(priv, priv->phymode, le16_to_cpu(priv->staging_rxon.channel)); if (!ch_info) @@ -2501,7 +2536,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) else priv->phymode = MODE_IEEE80211G; - iwl_set_flags_for_phymode(priv, priv->phymode); + iwl3945_set_flags_for_phymode(priv, priv->phymode); priv->staging_rxon.ofdm_basic_rates = (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; @@ -2509,15 +2544,12 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; } -static int iwl_set_mode(struct iwl_priv *priv, int mode) +static int iwl3945_set_mode(struct iwl3945_priv *priv, int mode) { - if (!iwl_is_ready_rf(priv)) - return -EAGAIN; - if (mode == IEEE80211_IF_TYPE_IBSS) { - const struct iwl_channel_info *ch_info; + const struct iwl3945_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, + ch_info = iwl3945_get_channel_info(priv, priv->phymode, le16_to_cpu(priv->staging_rxon.channel)); @@ -2528,32 +2560,36 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode) } } + priv->iw_mode = mode; + + iwl3945_connection_init_rx_config(priv); + memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); + + iwl3945_clear_stations_table(priv); + + /* dont commit rxon if rf-kill is on*/ + if (!iwl3945_is_ready_rf(priv)) + return -EAGAIN; + cancel_delayed_work(&priv->scan_check); - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl3945_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); return -EAGAIN; } - priv->iw_mode = mode; - - iwl_connection_init_rx_config(priv); - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - - iwl_clear_stations_table(priv); - - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); return 0; } -static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv, +static void iwl3945_build_tx_cmd_hwcrypto(struct iwl3945_priv *priv, struct ieee80211_tx_control *ctl, - struct iwl_cmd *cmd, + struct iwl3945_cmd *cmd, struct sk_buff *skb_frag, int last_frag) { - struct iwl_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo; + struct iwl3945_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo; switch (keyinfo->alg) { case ALG_CCMP: @@ -2596,8 +2632,8 @@ static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv, /* * handle build REPLY_TX command notification. */ -static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, - struct iwl_cmd *cmd, +static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, + struct iwl3945_cmd *cmd, struct ieee80211_tx_control *ctrl, struct ieee80211_hdr *hdr, int is_unicast, u8 std_id) @@ -2645,11 +2681,9 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) - cmd->cmd.tx.timeout.pm_frame_timeout = - cpu_to_le16(3); + cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); else - cmd->cmd.tx.timeout.pm_frame_timeout = - cpu_to_le16(2); + cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); } else cmd->cmd.tx.timeout.pm_frame_timeout = 0; @@ -2658,41 +2692,44 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, cmd->cmd.tx.next_frame_len = 0; } -static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) +/** + * iwl3945_get_sta_id - Find station's index within station table + */ +static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr) { int sta_id; u16 fc = le16_to_cpu(hdr->frame_control); - /* If this frame is broadcast or not data then use the broadcast - * station id */ + /* If this frame is broadcast or management, use broadcast station id */ if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || is_multicast_ether_addr(hdr->addr1)) return priv->hw_setting.bcast_sta_id; switch (priv->iw_mode) { - /* If this frame is part of a BSS network (we're a station), then - * we use the AP's station id */ + /* If we are a client station in a BSS network, use the special + * AP station entry (that's the only station we communicate with) */ case IEEE80211_IF_TYPE_STA: return IWL_AP_ID; /* If we are an AP, then find the station, or use BCAST */ case IEEE80211_IF_TYPE_AP: - sta_id = iwl_hw_find_station(priv, hdr->addr1); + sta_id = iwl3945_hw_find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; return priv->hw_setting.bcast_sta_id; - /* If this frame is part of a IBSS network, then we use the - * target specific station id */ + /* If this frame is going out to an IBSS network, find the station, + * or create a new station table entry */ case IEEE80211_IF_TYPE_IBSS: { DECLARE_MAC_BUF(mac); - sta_id = iwl_hw_find_station(priv, hdr->addr1); + /* Create new station table entry */ + sta_id = iwl3945_hw_find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; - sta_id = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC); + sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -2700,11 +2737,11 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", print_mac(mac, hdr->addr1)); - iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); + iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; } default: - IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode); + IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); return priv->hw_setting.bcast_sta_id; } } @@ -2712,18 +2749,18 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* * start REPLY_TX command process */ -static int iwl_tx_skb(struct iwl_priv *priv, +static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb, struct ieee80211_tx_control *ctl) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_tfd_frame *tfd; + struct iwl3945_tfd_frame *tfd; u32 *control_flags; int txq_id = ctl->queue; - struct iwl_tx_queue *txq = NULL; - struct iwl_queue *q = NULL; + struct iwl3945_tx_queue *txq = NULL; + struct iwl3945_queue *q = NULL; dma_addr_t phys_addr; dma_addr_t txcmd_phys; - struct iwl_cmd *out_cmd = NULL; + struct iwl3945_cmd *out_cmd = NULL; u16 len, idx, len_org; u8 id, hdr_len, unicast; u8 sta_id; @@ -2735,7 +2772,7 @@ static int iwl_tx_skb(struct iwl_priv *priv, int rc; spin_lock_irqsave(&priv->lock, flags); - if (iwl_is_rfkill(priv)) { + if (iwl3945_is_rfkill(priv)) { IWL_DEBUG_DROP("Dropping - RF KILL\n"); goto drop_unlock; } @@ -2755,7 +2792,7 @@ static int iwl_tx_skb(struct iwl_priv *priv, fc = le16_to_cpu(hdr->frame_control); -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL3945_DEBUG if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); else if (ieee80211_is_assoc_request(fc)) @@ -2764,16 +2801,19 @@ static int iwl_tx_skb(struct iwl_priv *priv, IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - if (!iwl_is_associated(priv) && + /* drop all data frame if we are not associated */ + if (!iwl3945_is_associated(priv) && !priv->assoc_id && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { - IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n"); + IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; } spin_unlock_irqrestore(&priv->lock, flags); hdr_len = ieee80211_get_hdrlen(fc); - sta_id = iwl_get_sta_id(priv, hdr); + + /* Find (or create) index into station table for destination station */ + sta_id = iwl3945_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { DECLARE_MAC_BUF(mac); @@ -2794,32 +2834,54 @@ static int iwl_tx_skb(struct iwl_priv *priv, __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); seq_number += 0x10; } + + /* Descriptor for chosen Tx queue */ txq = &priv->txq[txq_id]; q = &txq->q; spin_lock_irqsave(&priv->lock, flags); - tfd = &txq->bd[q->first_empty]; + /* Set up first empty TFD within this queue's circular TFD buffer */ + tfd = &txq->bd[q->write_ptr]; memset(tfd, 0, sizeof(*tfd)); control_flags = (u32 *) tfd; - idx = get_cmd_index(q, q->first_empty, 0); + idx = get_cmd_index(q, q->write_ptr, 0); - memset(&(txq->txb[q->first_empty]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->first_empty].skb[0] = skb; - memcpy(&(txq->txb[q->first_empty].status.control), + /* Set up driver data for this TFD */ + memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl3945_tx_info)); + txq->txb[q->write_ptr].skb[0] = skb; + memcpy(&(txq->txb[q->write_ptr].status.control), ctl, sizeof(struct ieee80211_tx_control)); + + /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = &txq->cmd[idx]; memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); + + /* + * Set up the Tx-command (not MAC!) header. + * Store the chosen Tx queue and TFD index within the sequence field; + * after Tx, uCode's Tx response will return this value so driver can + * locate the frame within the tx queue and do post-tx processing. + */ out_cmd->hdr.cmd = REPLY_TX; out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->first_empty))); - /* copy frags header */ + INDEX_TO_SEQ(q->write_ptr))); + + /* Copy MAC header from skb into command buffer */ memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); - /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */ + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ len = priv->hw_setting.tx_cmd_len + - sizeof(struct iwl_cmd_header) + hdr_len; + sizeof(struct iwl3945_cmd_header) + hdr_len; len_org = len; len = (len + 3) & ~3; @@ -2829,37 +2891,45 @@ static int iwl_tx_skb(struct iwl_priv *priv, else len_org = 0; - txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx + - offsetof(struct iwl_cmd, hdr); + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl3945_cmd) * idx + + offsetof(struct iwl3945_cmd, hdr); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); + /* Add buffer containing Tx command and MAC(!) header to TFD's + * first entry */ + iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) - iwl_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); + iwl3945_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); - /* 802.11 null functions have no payload... */ + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ len = skb->len - hdr_len; if (len) { phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); + iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); } - /* If there is no payload, then only one TFD is used */ if (!len) + /* If there is no payload, then we use only one Tx buffer */ *control_flags = TFD_CTL_COUNT_SET(1); else + /* Else use 2 buffers. + * Tell 3945 about any padding after MAC header */ *control_flags = TFD_CTL_COUNT_SET(2) | TFD_CTL_PAD_SET(U32_PAD(len)); + /* Total # bytes to be transmitted */ len = (u16)skb->len; out_cmd->cmd.tx.len = cpu_to_le16(len); /* TODO need this for burst mode later on */ - iwl_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); + iwl3945_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); /* set is_hcca to 0; it probably will never be implemented */ - iwl_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); + iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; @@ -2875,25 +2945,26 @@ static int iwl_tx_skb(struct iwl_priv *priv, txq->need_update = 0; } - iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, + iwl3945_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, sizeof(out_cmd->cmd.tx)); - iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, + iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, ieee80211_get_hdrlen(fc)); - q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd); - rc = iwl_tx_queue_update_write_ptr(priv, txq); + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl3945_queue_inc_wrap(q->write_ptr, q->n_bd); + rc = iwl3945_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); if (rc) return rc; - if ((iwl_queue_space(q) < q->high_mark) + if ((iwl3945_queue_space(q) < q->high_mark) && priv->mac80211_registered) { if (wait_write_ptr) { spin_lock_irqsave(&priv->lock, flags); txq->need_update = 1; - iwl_tx_queue_update_write_ptr(priv, txq); + iwl3945_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); } @@ -2908,13 +2979,13 @@ drop: return -1; } -static void iwl_set_rate(struct iwl_priv *priv) +static void iwl3945_set_rate(struct iwl3945_priv *priv) { const struct ieee80211_hw_mode *hw = NULL; struct ieee80211_rate *rate; int i; - hw = iwl_get_hw_mode(priv, priv->phymode); + hw = iwl3945_get_hw_mode(priv, priv->phymode); if (!hw) { IWL_ERROR("Failed to set rate: unable to get hw mode\n"); return; @@ -2932,7 +3003,7 @@ static void iwl_set_rate(struct iwl_priv *priv) if ((rate->val < IWL_RATE_COUNT) && (rate->flags & IEEE80211_RATE_SUPPORTED)) { IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", - rate->val, iwl_rates[rate->val].plcp, + rate->val, iwl3945_rates[rate->val].plcp, (rate->flags & IEEE80211_RATE_BASIC) ? "*" : ""); priv->active_rate |= (1 << rate->val); @@ -2940,7 +3011,7 @@ static void iwl_set_rate(struct iwl_priv *priv) priv->active_rate_basic |= (1 << rate->val); } else IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", - rate->val, iwl_rates[rate->val].plcp); + rate->val, iwl3945_rates[rate->val].plcp); } IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", @@ -2969,7 +3040,7 @@ static void iwl_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } -static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) +static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) { unsigned long flags; @@ -2980,21 +3051,21 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) disable_radio ? "OFF" : "ON"); if (disable_radio) { - iwl_scan_cancel(priv); + iwl3945_scan_cancel(priv); /* FIXME: This is a workaround for AP */ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_SW_BIT_RFKILL); spin_unlock_irqrestore(&priv->lock, flags); - iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); + iwl3945_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); set_bit(STATUS_RF_KILL_SW, &priv->status); } return; } spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); clear_bit(STATUS_RF_KILL_SW, &priv->status); spin_unlock_irqrestore(&priv->lock, flags); @@ -3003,9 +3074,9 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) msleep(10); spin_lock_irqsave(&priv->lock, flags); - iwl_read32(priv, CSR_UCODE_DRV_GP1); - if (!iwl_grab_restricted_access(priv)) - iwl_release_restricted_access(priv); + iwl3945_read32(priv, CSR_UCODE_DRV_GP1); + if (!iwl3945_grab_nic_access(priv)) + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { @@ -3018,7 +3089,7 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) return; } -void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, +void iwl3945_set_decrypted_flag(struct iwl3945_priv *priv, struct sk_buff *skb, u32 decrypt_res, struct ieee80211_rx_status *stats) { u16 fc = @@ -3050,13 +3121,13 @@ void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, } } -void iwl_handle_data_packet_monitor(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, +void iwl3945_handle_data_packet_monitor(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb, void *data, short len, struct ieee80211_rx_status *stats, u16 phy_flags) { - struct iwl_rt_rx_hdr *iwl_rt; + struct iwl3945_rt_rx_hdr *iwl3945_rt; /* First cache any information we need before we overwrite * the information provided in the skb from the hardware */ @@ -3067,26 +3138,26 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, __le16 phy_flags_hw = cpu_to_le16(phy_flags); /* We received data from the HW, so stop the watchdog */ - if (len > IWL_RX_BUF_SIZE - sizeof(*iwl_rt)) { + if (len > IWL_RX_BUF_SIZE - sizeof(*iwl3945_rt)) { IWL_DEBUG_DROP("Dropping too large packet in monitor\n"); return; } /* copy the frame data to write after where the radiotap header goes */ - iwl_rt = (void *)rxb->skb->data; - memmove(iwl_rt->payload, data, len); + iwl3945_rt = (void *)rxb->skb->data; + memmove(iwl3945_rt->payload, data, len); - iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; - iwl_rt->rt_hdr.it_pad = 0; /* always good to zero */ + iwl3945_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; + iwl3945_rt->rt_hdr.it_pad = 0; /* always good to zero */ /* total header + data */ - iwl_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl_rt)); + iwl3945_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl3945_rt)); /* Set the size of the skb to the size of the frame */ - skb_put(rxb->skb, sizeof(*iwl_rt) + len); + skb_put(rxb->skb, sizeof(*iwl3945_rt) + len); /* Big bitfield of all the fields we provide in radiotap */ - iwl_rt->rt_hdr.it_present = + iwl3945_rt->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | (1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | @@ -3096,39 +3167,39 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, (1 << IEEE80211_RADIOTAP_ANTENNA)); /* Zero the flags, we'll add to them as we go */ - iwl_rt->rt_flags = 0; + iwl3945_rt->rt_flags = 0; - iwl_rt->rt_tsf = cpu_to_le64(tsf); + iwl3945_rt->rt_tsf = cpu_to_le64(tsf); /* Convert to dBm */ - iwl_rt->rt_dbmsignal = signal; - iwl_rt->rt_dbmnoise = noise; + iwl3945_rt->rt_dbmsignal = signal; + iwl3945_rt->rt_dbmnoise = noise; /* Convert the channel frequency and set the flags */ - iwl_rt->rt_channelMHz = cpu_to_le16(stats->freq); + iwl3945_rt->rt_channelMHz = cpu_to_le16(stats->freq); if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) - iwl_rt->rt_chbitmask = + iwl3945_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ)); else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) - iwl_rt->rt_chbitmask = + iwl3945_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ)); else /* 802.11g */ - iwl_rt->rt_chbitmask = + iwl3945_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ)); - rate = iwl_rate_index_from_plcp(rate); + rate = iwl3945_rate_index_from_plcp(rate); if (rate == -1) - iwl_rt->rt_rate = 0; + iwl3945_rt->rt_rate = 0; else - iwl_rt->rt_rate = iwl_rates[rate].ieee; + iwl3945_rt->rt_rate = iwl3945_rates[rate].ieee; /* antenna number */ - iwl_rt->rt_antenna = + iwl3945_rt->rt_antenna = le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; /* set the preamble flag if we have it */ if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) - iwl_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + iwl3945_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); @@ -3140,7 +3211,7 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, #define IWL_PACKET_RETRY_TIME HZ -int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) +int iwl3945_is_duplicate_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *header) { u16 sc = le16_to_cpu(header->seq_ctrl); u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; @@ -3151,29 +3222,26 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) switch (priv->iw_mode) { case IEEE80211_IF_TYPE_IBSS:{ struct list_head *p; - struct iwl_ibss_seq *entry = NULL; + struct iwl3945_ibss_seq *entry = NULL; u8 *mac = header->addr2; int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); __list_for_each(p, &priv->ibss_mac_hash[index]) { - entry = - list_entry(p, struct iwl_ibss_seq, list); + entry = list_entry(p, struct iwl3945_ibss_seq, list); if (!compare_ether_addr(entry->mac, mac)) break; } if (p == &priv->ibss_mac_hash[index]) { entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) { - IWL_ERROR - ("Cannot malloc new mac entry\n"); + IWL_ERROR("Cannot malloc new mac entry\n"); return 0; } memcpy(entry->mac, mac, ETH_ALEN); entry->seq_num = seq; entry->frag_num = frag; entry->packet_time = jiffies; - list_add(&entry->list, - &priv->ibss_mac_hash[index]); + list_add(&entry->list, &priv->ibss_mac_hash[index]); return 0; } last_seq = &entry->seq_num; @@ -3207,7 +3275,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) return 1; } -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT #include "iwl-spectrum.h" @@ -3222,7 +3290,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) * the lower 3 bytes is the time in usec within one beacon interval */ -static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval) +static u32 iwl3945_usecs_to_beacons(u32 usec, u32 beacon_interval) { u32 quot; u32 rem; @@ -3241,7 +3309,7 @@ static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval) * the same as HW timer counter counting down */ -static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) +static __le32 iwl3945_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) { u32 base_low = base & BEACON_TIME_MASK_LOW; u32 addon_low = addon & BEACON_TIME_MASK_LOW; @@ -3260,13 +3328,13 @@ static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) return cpu_to_le32(res); } -static int iwl_get_measurement(struct iwl_priv *priv, +static int iwl3945_get_measurement(struct iwl3945_priv *priv, struct ieee80211_measurement_params *params, u8 type) { - struct iwl_spectrum_cmd spectrum; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { + struct iwl3945_spectrum_cmd spectrum; + struct iwl3945_rx_packet *res; + struct iwl3945_host_cmd cmd = { .id = REPLY_SPECTRUM_MEASUREMENT_CMD, .data = (void *)&spectrum, .meta.flags = CMD_WANT_SKB, @@ -3276,9 +3344,9 @@ static int iwl_get_measurement(struct iwl_priv *priv, int spectrum_resp_status; int duration = le16_to_cpu(params->duration); - if (iwl_is_associated(priv)) + if (iwl3945_is_associated(priv)) add_time = - iwl_usecs_to_beacons( + iwl3945_usecs_to_beacons( le64_to_cpu(params->start_time) - priv->last_tsf, le16_to_cpu(priv->rxon_timing.beacon_interval)); @@ -3291,9 +3359,9 @@ static int iwl_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 (iwl3945_is_associated(priv)) spectrum.start_time = - iwl_add_beacon_time(priv->last_beacon_time, + iwl3945_add_beacon_time(priv->last_beacon_time, add_time, le16_to_cpu(priv->rxon_timing.beacon_interval)); else @@ -3306,11 +3374,11 @@ static int iwl_get_measurement(struct iwl_priv *priv, spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl3945_send_cmd_sync(priv, &cmd); if (rc) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl3945_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); rc = -EIO; @@ -3320,9 +3388,8 @@ static int iwl_get_measurement(struct iwl_priv *priv, switch (spectrum_resp_status) { case 0: /* Command will be handled */ if (res->u.spectrum.id != 0xff) { - IWL_DEBUG_INFO - ("Replaced existing measurement: %d\n", - res->u.spectrum.id); + IWL_DEBUG_INFO("Replaced existing measurement: %d\n", + res->u.spectrum.id); priv->measurement_status &= ~MEASUREMENT_READY; } priv->measurement_status |= MEASUREMENT_ACTIVE; @@ -3340,8 +3407,8 @@ static int iwl_get_measurement(struct iwl_priv *priv, } #endif -static void iwl_txstatus_to_ieee(struct iwl_priv *priv, - struct iwl_tx_info *tx_sta) +static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv, + struct iwl3945_tx_info *tx_sta) { tx_sta->status.ack_signal = 0; @@ -3360,41 +3427,41 @@ static void iwl_txstatus_to_ieee(struct iwl_priv *priv, } /** - * iwl_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC. + * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd * - * When FW advances 'R' index, all entries between old and - * new 'R' index need to be reclaimed. As result, some free space - * forms. If there is enough free space (> low mark), wake Tx queue. + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. */ -int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) +static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index) { - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; + struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; + struct iwl3945_queue *q = &txq->q; int nfreed = 0; if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " "is out of range [0-%d] %d %d.\n", txq_id, - index, q->n_bd, q->first_empty, q->last_used); + index, q->n_bd, q->write_ptr, q->read_ptr); return 0; } - for (index = iwl_queue_inc_wrap(index, q->n_bd); - q->last_used != index; - q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) { + for (index = iwl3945_queue_inc_wrap(index, q->n_bd); + q->read_ptr != index; + q->read_ptr = iwl3945_queue_inc_wrap(q->read_ptr, q->n_bd)) { if (txq_id != IWL_CMD_QUEUE_NUM) { - iwl_txstatus_to_ieee(priv, - &(txq->txb[txq->q.last_used])); - iwl_hw_txq_free_tfd(priv, txq); + iwl3945_txstatus_to_ieee(priv, + &(txq->txb[txq->q.read_ptr])); + iwl3945_hw_txq_free_tfd(priv, txq); } else if (nfreed > 1) { IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, - q->first_empty, q->last_used); + q->write_ptr, q->read_ptr); queue_work(priv->workqueue, &priv->restart); } nfreed++; } - if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && + if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) && (txq_id != IWL_CMD_QUEUE_NUM) && priv->mac80211_registered) ieee80211_wake_queue(priv->hw, txq_id); @@ -3403,7 +3470,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) return nfreed; } -static int iwl_is_tx_success(u32 status) +static int iwl3945_is_tx_success(u32 status) { return (status & 0xFF) == 0x1; } @@ -3413,27 +3480,30 @@ static int iwl_is_tx_success(u32 status) * Generic RX handler implementations * ******************************************************************************/ -static void iwl_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +/** + * iwl3945_rx_reply_tx - Handle Tx response + */ +static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl3945_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_status *tx_status; - struct iwl_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le32_to_cpu(tx_resp->status); if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.first_empty, - txq->q.last_used); + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); return; } - tx_status = &(txq->txb[txq->q.last_used].status); + tx_status = &(txq->txb[txq->q.read_ptr].status); tx_status->retry_count = tx_resp->failure_frame; tx_status->queue_number = status; @@ -3441,28 +3511,28 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv, tx_status->queue_length |= tx_resp->failure_rts; tx_status->flags = - iwl_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; + iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; - tx_status->control.tx_rate = iwl_rate_index_from_plcp(tx_resp->rate); + tx_status->control.tx_rate = iwl3945_rate_index_from_plcp(tx_resp->rate); IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n", - txq_id, iwl_get_tx_fail_reason(status), status, + txq_id, iwl3945_get_tx_fail_reason(status), status, tx_resp->rate, tx_resp->failure_frame); IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); if (index != -1) - iwl_tx_queue_reclaim(priv, txq_id, index); + iwl3945_tx_queue_reclaim(priv, txq_id, index); if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); } -static void iwl_rx_reply_alive(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_alive_resp *palive; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_alive_resp *palive; struct delayed_work *pwork; palive = &pkt->u.alive_frame; @@ -3476,14 +3546,14 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, IWL_DEBUG_INFO("Initialization Alive received.\n"); memcpy(&priv->card_alive_init, &pkt->u.alive_frame, - sizeof(struct iwl_init_alive_resp)); + sizeof(struct iwl3945_init_alive_resp)); pwork = &priv->init_alive_start; } else { IWL_DEBUG_INFO("Runtime Alive received.\n"); memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); + sizeof(struct iwl3945_alive_resp)); pwork = &priv->alive_start; - iwl_disable_events(priv); + iwl3945_disable_events(priv); } /* We delay the ALIVE response by 5ms to @@ -3495,19 +3565,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, IWL_WARNING("uCode did not respond OK.\n"); } -static void iwl_rx_reply_add_sta(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_reply_add_sta(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); return; } -static void iwl_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_reply_error(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " "seq 0x%04X ser 0x%08X\n", @@ -3520,23 +3590,23 @@ static void iwl_rx_reply_error(struct iwl_priv *priv, #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x -static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_csa(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; - struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rxon_cmd *rxon = (void *)&priv->active_rxon; + struct iwl3945_csa_notification *csa = &(pkt->u.csa_notif); IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); rxon->channel = csa->channel; priv->staging_rxon.channel = csa->channel; } -static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_spectrum_measure_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_spectrum_notification *report = &(pkt->u.spectrum_notif); if (!report->state) { IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, @@ -3549,31 +3619,31 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, #endif } -static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_pm_sleep_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); +#ifdef CONFIG_IWL3945_DEBUG + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_sleep_notification *sleep = &(pkt->u.sleep_notif); IWL_DEBUG_RX("sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif } -static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_pm_debug_statistics_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " "notification for %s:\n", le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); + iwl3945_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); } -static void iwl_bg_beacon_update(struct work_struct *work) +static void iwl3945_bg_beacon_update(struct work_struct *work) { - struct iwl_priv *priv = - container_of(work, struct iwl_priv, beacon_update); + struct iwl3945_priv *priv = + container_of(work, struct iwl3945_priv, beacon_update); struct sk_buff *beacon; /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ @@ -3592,15 +3662,15 @@ static void iwl_bg_beacon_update(struct work_struct *work) priv->ibss_beacon = beacon; mutex_unlock(&priv->mutex); - iwl_send_beacon_cmd(priv); + iwl3945_send_beacon_cmd(priv); } -static void iwl_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_beacon_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWL3945_DEBUG + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); u8 rate = beacon->beacon_notify_hdr.rate; IWL_DEBUG_RX("beacon status %x retries %d iss %d " @@ -3618,25 +3688,25 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, } /* Service response to REPLY_SCAN_CMD (0x80) */ -static void iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_reply_scan(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanreq_notification *notif = - (struct iwl_scanreq_notification *)pkt->u.raw; +#ifdef CONFIG_IWL3945_DEBUG + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_scanreq_notification *notif = + (struct iwl3945_scanreq_notification *)pkt->u.raw; IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); #endif } /* Service SCAN_START_NOTIFICATION (0x82) */ -static void iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_scan_start_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanstart_notification *notif = - (struct iwl_scanstart_notification *)pkt->u.raw; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_scanstart_notification *notif = + (struct iwl3945_scanstart_notification *)pkt->u.raw; priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); IWL_DEBUG_SCAN("Scan start: " "%d [802.11%s] " @@ -3648,12 +3718,12 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, } /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ -static void iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_scan_results_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanresults_notification *notif = - (struct iwl_scanresults_notification *)pkt->u.raw; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_scanresults_notification *notif = + (struct iwl3945_scanresults_notification *)pkt->u.raw; IWL_DEBUG_SCAN("Scan ch.res: " "%d [802.11%s] " @@ -3669,14 +3739,15 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ -static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_scancomplete_notification *scan_notif = (void *)pkt->u.raw; IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", scan_notif->scanned_channels, @@ -3711,6 +3782,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; IWL_DEBUG_INFO("Setting scan to off\n"); clear_bit(STATUS_SCANNING, &priv->status); @@ -3729,10 +3801,10 @@ reschedule: /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ -static void iwl_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_rx_card_state_notif(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data; u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); unsigned long status = priv->status; @@ -3740,7 +3812,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, (flags & HW_CARD_DISABLED) ? "Kill" : "On", (flags & SW_CARD_DISABLED) ? "Kill" : "On"); - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); if (flags & HW_CARD_DISABLED) @@ -3754,7 +3826,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, else clear_bit(STATUS_RF_KILL_SW, &priv->status); - iwl_scan_cancel(priv); + iwl3945_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) || @@ -3766,7 +3838,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, } /** - * iwl_setup_rx_handlers - Initialize Rx handler callbacks + * iwl3945_setup_rx_handlers - Initialize Rx handler callbacks * * Setup the RX handlers for each of the reply types sent from the uCode * to the host. @@ -3774,61 +3846,58 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, * This function chains into the hardware specific files for them to setup * any hardware specific handlers as well. */ -static void iwl_setup_rx_handlers(struct iwl_priv *priv) +static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv) { - priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; - priv->rx_handlers[REPLY_ADD_STA] = iwl_rx_reply_add_sta; - priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; - priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + priv->rx_handlers[REPLY_ALIVE] = iwl3945_rx_reply_alive; + priv->rx_handlers[REPLY_ADD_STA] = iwl3945_rx_reply_add_sta; + priv->rx_handlers[REPLY_ERROR] = iwl3945_rx_reply_error; + priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl3945_rx_csa; priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; - priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; + iwl3945_rx_spectrum_measure_notif; + priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl3945_rx_pm_sleep_notif; priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = - iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; - - /* NOTE: iwl_rx_statistics is different based on whether - * the build is for the 3945 or the 4965. See the - * corresponding implementation in iwl-XXXX.c - * - * The same handler is used for both the REPLY to a - * discrete statistics request from the host as well as - * for the periodic statistics notification from the uCode + iwl3945_rx_pm_debug_statistics_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl3945_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_hw_rx_statistics; - priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_hw_rx_statistics; + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics; + priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics; - priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan; - priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif; + priv->rx_handlers[REPLY_SCAN_CMD] = iwl3945_rx_reply_scan; + priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl3945_rx_scan_start_notif; priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = - iwl_rx_scan_results_notif; + iwl3945_rx_scan_results_notif; priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = - iwl_rx_scan_complete_notif; - priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; - priv->rx_handlers[REPLY_TX] = iwl_rx_reply_tx; + iwl3945_rx_scan_complete_notif; + priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif; + priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx; - /* Setup hardware specific Rx handlers */ - iwl_hw_rx_handler_setup(priv); + /* Set up hardware specific Rx handlers */ + iwl3945_hw_rx_handler_setup(priv); } /** - * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them + * iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them * @rxb: Rx buffer to reclaim * * If an Rx buffer has an async callback associated with it the callback * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -static void iwl_tx_cmd_complete(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv, + struct iwl3945_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); int huge = sequence & SEQ_HUGE_FRAME; int cmd_index; - struct iwl_cmd *cmd; + struct iwl3945_cmd *cmd; /* 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 @@ -3849,7 +3918,7 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, !cmd->meta.u.callback(priv, cmd, rxb->skb)) rxb->skb = NULL; - iwl_tx_queue_reclaim(priv, txq_id, index); + iwl3945_tx_queue_reclaim(priv, txq_id, index); if (!(cmd->meta.flags & CMD_ASYNC)) { clear_bit(STATUS_HCMD_ACTIVE, &priv->status); @@ -3879,10 +3948,10 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * The queue is empty (no good data) if WRITE = READ - 1, and is full if * WRITE = READ. * - * During initialization the host sets up the READ queue position to the first + * During initialization, the host sets up the READ queue position to the first * INDEX position, and WRITE to the last (READ - 1 wrapped) * - * When the firmware places a packet in a buffer it will advance the READ index + * When the firmware places a packet in a buffer, it will advance the READ index * and fire the RX interrupt. The driver can then query the READ index and * process as many packets as possible, moving the WRITE index forward as it * resets the Rx queue buffers with new memory. @@ -3890,8 +3959,8 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * The management in the driver is as follows: * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replensish the iwl->rxq->rx_free. - * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the + * to replenish the iwl->rxq->rx_free. + * + In iwl3945_rx_replenish (scheduled) if 'processed' != 'read' then the * iwl->rxq is replenished and the READ INDEX is updated (updating the * 'processed' and 'read' driver indexes as well) * + A received packet is processed and handed to the kernel network stack, @@ -3904,28 +3973,28 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * * Driver sequence: * - * iwl_rx_queue_alloc() Allocates rx_free - * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl_rx_queue_restock - * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx + * iwl3945_rx_queue_alloc() Allocates rx_free + * iwl3945_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl3945_rx_queue_restock + * iwl3945_rx_queue_restock() Moves available buffers from rx_free into Rx * queue, updates firmware pointers, and updates * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl_rx_replenish + * are available, schedules iwl3945_rx_replenish * * -- enable interrupts -- - * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the + * ISR - iwl3945_rx() Detach iwl3945_rx_mem_buffers from pool up to the * READ INDEX, detaching the SKB from the pool. * Moves the packet buffer from queue to rx_used. - * Calls iwl_rx_queue_restock to refill any empty + * Calls iwl3945_rx_queue_restock to refill any empty * slots. * ... * */ /** - * iwl_rx_queue_space - Return number of free slots available in queue. + * iwl3945_rx_queue_space - Return number of free slots available in queue. */ -static int iwl_rx_queue_space(const struct iwl_rx_queue *q) +static int iwl3945_rx_queue_space(const struct iwl3945_rx_queue *q) { int s = q->read - q->write; if (s <= 0) @@ -3938,15 +4007,9 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q) } /** - * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue - * - * NOTE: This function has 3945 and 4965 specific code sections - * but is declared in base due to the majority of the - * implementation being the same (only a numeric constant is - * different) - * + * iwl3945_rx_queue_update_write_ptr - Update the write pointer for the RX queue */ -int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) +int iwl3945_rx_queue_update_write_ptr(struct iwl3945_priv *priv, struct iwl3945_rx_queue *q) { u32 reg = 0; int rc = 0; @@ -3957,24 +4020,29 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) if (q->need_update == 0) goto exit_unlock; + /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &priv->status)) { - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { - iwl_set_bit(priv, CSR_GP_CNTRL, + iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); goto exit_unlock; } - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) goto exit_unlock; - iwl_write_restricted(priv, FH_RSCSR_CHNL0_WPTR, + /* Device expects a multiple of 8 */ + iwl3945_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); + + /* Else device is assumed to be awake */ } else - iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); + /* Device expects a multiple of 8 */ + iwl3945_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); q->need_update = 0; @@ -3985,42 +4053,43 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) } /** - * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer pointer. - * - * NOTE: This function has 3945 and 4965 specific code paths in it. + * iwl3945_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr */ -static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, +static inline __le32 iwl3945_dma_addr2rbd_ptr(struct iwl3945_priv *priv, dma_addr_t dma_addr) { return cpu_to_le32((u32)dma_addr); } /** - * iwl_rx_queue_restock - refill RX queue from pre-allocated pool + * iwl3945_rx_queue_restock - refill RX queue from pre-allocated pool * - * If there are slots in the RX queue that need to be restocked, + * If there are slots in the RX queue that need to be restocked, * and we have free pre-allocated buffers, fill the ranks as much - * as we can pulling from rx_free. + * as we can, pulling from rx_free. * * This moves the 'write' index forward to catch up with 'processed', and * also updates the memory address in the firmware to reference the new * target buffer. */ -int iwl_rx_queue_restock(struct iwl_priv *priv) +static int iwl3945_rx_queue_restock(struct iwl3945_priv *priv) { - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl3945_rx_queue *rxq = &priv->rxq; struct list_head *element; - struct iwl_rx_mem_buffer *rxb; + struct iwl3945_rx_mem_buffer *rxb; unsigned long flags; int write, rc; spin_lock_irqsave(&rxq->lock, flags); write = rxq->write & ~0x7; - while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + while ((iwl3945_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* Get next free Rx buffer, remove from free list */ element = rxq->rx_free.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); list_del(element); - rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl3945_dma_addr2rbd_ptr(priv, rxb->dma_addr); rxq->queue[rxq->write] = rxb; rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; rxq->free_count--; @@ -4032,13 +4101,14 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->rx_replenish); - /* If we've added more space for the firmware to place data, tell it */ + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ if ((write != (rxq->write & ~0x7)) || (abs(rxq->write - rxq->read) > 7)) { spin_lock_irqsave(&rxq->lock, flags); rxq->need_update = 1; spin_unlock_irqrestore(&rxq->lock, flags); - rc = iwl_rx_queue_update_write_ptr(priv, rxq); + rc = iwl3945_rx_queue_update_write_ptr(priv, rxq); if (rc) return rc; } @@ -4047,24 +4117,25 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) } /** - * iwl_rx_replensih - Move all used packet from rx_used to rx_free + * iwl3945_rx_replenish - Move all used packet from rx_used to rx_free * * When moving to rx_free an SKB is allocated for the slot. * - * Also restock the Rx queue via iwl_rx_queue_restock. - * This is called as a scheduled work item (except for during intialization) + * Also restock the Rx queue via iwl3945_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) */ -void iwl_rx_replenish(void *data) +static void iwl3945_rx_allocate(struct iwl3945_priv *priv) { - struct iwl_priv *priv = data; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl3945_rx_queue *rxq = &priv->rxq; struct list_head *element; - struct iwl_rx_mem_buffer *rxb; + struct iwl3945_rx_mem_buffer *rxb; unsigned long flags; spin_lock_irqsave(&rxq->lock, flags); while (!list_empty(&rxq->rx_used)) { element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + rxb = list_entry(element, struct iwl3945_rx_mem_buffer, list); + + /* Alloc a new receive buffer */ rxb->skb = alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); if (!rxb->skb) { @@ -4078,6 +4149,8 @@ void iwl_rx_replenish(void *data) } priv->alloc_rxb_skb++; list_del(element); + + /* Get physical address of RB/SKB */ rxb->dma_addr = pci_map_single(priv->pci_dev, rxb->skb->data, IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); @@ -4085,18 +4158,38 @@ void iwl_rx_replenish(void *data) rxq->free_count++; } spin_unlock_irqrestore(&rxq->lock, flags); +} + +/* + * this should be called while priv->lock is locked + */ +void __iwl3945_rx_replenish(void *data) +{ + struct iwl3945_priv *priv = data; + + iwl3945_rx_allocate(priv); + iwl3945_rx_queue_restock(priv); +} + + +void iwl3945_rx_replenish(void *data) +{ + struct iwl3945_priv *priv = data; + unsigned long flags; + + iwl3945_rx_allocate(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_rx_queue_restock(priv); + iwl3945_rx_queue_restock(priv); spin_unlock_irqrestore(&priv->lock, flags); } /* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have it's SKB set to NULL + * If an SKB has been detached, the POOL needs to have its SKB set to NULL * This free routine walks the list of POOL entries and if SKB is set to * non NULL it is unmapped and freed */ -void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +static void iwl3945_rx_queue_free(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) { int i; for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { @@ -4113,21 +4206,25 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) rxq->bd = NULL; } -int iwl_rx_queue_alloc(struct iwl_priv *priv) +int iwl3945_rx_queue_alloc(struct iwl3945_priv *priv) { - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl3945_rx_queue *rxq = &priv->rxq; struct pci_dev *dev = priv->pci_dev; int i; spin_lock_init(&rxq->lock); INIT_LIST_HEAD(&rxq->rx_free); INIT_LIST_HEAD(&rxq->rx_used); + + /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); if (!rxq->bd) return -ENOMEM; + /* Fill the rx_used queue with _all_ of the Rx buffers */ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; @@ -4136,7 +4233,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) return 0; } -void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +void iwl3945_rx_queue_reset(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq) { unsigned long flags; int i; @@ -4183,7 +4280,7 @@ static u8 ratio2dB[100] = { /* Calculates a relative dB value from a ratio of linear * (i.e. not dB) signal levels. * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ -int iwl_calc_db_from_ratio(int sig_ratio) +int iwl3945_calc_db_from_ratio(int sig_ratio) { /* Anything above 1000:1 just report as 60 dB */ if (sig_ratio > 1000) @@ -4209,7 +4306,7 @@ int iwl_calc_db_from_ratio(int sig_ratio) /* Calculate an indication of rx signal quality (a percentage, not dBm!). * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info * about formulas used below. */ -int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) +int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm) { int sig_qual; int degradation = PERFECT_RSSI - rssi_dbm; @@ -4244,24 +4341,30 @@ int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) } /** - * iwl_rx_handle - Main entry function for receiving responses from the uCode + * iwl3945_rx_handle - Main entry function for receiving responses from uCode * * Uses the priv->rx_handlers callback function array to invoke * the appropriate handlers, including command responses, * frame-received notifications, and other notifications. */ -static void iwl_rx_handle(struct iwl_priv *priv) +static void iwl3945_rx_handle(struct iwl3945_priv *priv) { - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl3945_rx_mem_buffer *rxb; + struct iwl3945_rx_packet *pkt; + struct iwl3945_rx_queue *rxq = &priv->rxq; u32 r, i; int reclaim; unsigned long flags; + u8 fill_rx = 0; + u32 count = 0; - r = iwl_hw_get_rx_read(priv); + /* uCode's read index (stored in shared DRAM) indicates the last Rx + * buffer that the driver may process (last buffer filled by ucode). */ + r = iwl3945_hw_get_rx_read(priv); i = rxq->read; + if (iwl3945_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; /* Rx interrupt, but nothing sent from uCode */ if (i == r) IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); @@ -4269,7 +4372,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) while (i != r) { rxb = rxq->queue[i]; - /* If an RXB doesn't have a queue slot associated with it + /* If an RXB doesn't have a Rx queue slot associated with it, * then a bug has been introduced in the queue refilling * routines -- catch it here */ BUG_ON(rxb == NULL); @@ -4279,7 +4382,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - pkt = (struct iwl_rx_packet *)rxb->skb->data; + pkt = (struct iwl3945_rx_packet *)rxb->skb->data; /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -4293,7 +4396,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) /* Based on type of command response or notification, * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ + * rx_handlers table. See iwl3945_setup_rx_handlers() */ if (priv->rx_handlers[pkt->hdr.cmd]) { IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d, %s, 0x%02x\n", r, i, @@ -4308,11 +4411,11 @@ static void iwl_rx_handle(struct iwl_priv *priv) } if (reclaim) { - /* Invoke any callbacks, transfer the skb to caller, - * and fire off the (possibly) blocking iwl_send_cmd() + /* Invoke any callbacks, transfer the skb to caller, and + * fire off the (possibly) blocking iwl3945_send_cmd() * as we reclaim the driver command queue */ if (rxb && rxb->skb) - iwl_tx_cmd_complete(priv, rxb); + iwl3945_tx_cmd_complete(priv, rxb); else IWL_WARNING("Claim null rxb?\n"); } @@ -4332,15 +4435,28 @@ static void iwl_rx_handle(struct iwl_priv *priv) list_add_tail(&rxb->list, &priv->rxq.rx_used); spin_unlock_irqrestore(&rxq->lock, flags); i = (i + 1) & RX_QUEUE_MASK; + /* If there are a lot of unused frames, + * restock the Rx queue so ucode won't assert. */ + if (fill_rx) { + count++; + if (count >= 8) { + priv->rxq.read = i; + __iwl3945_rx_replenish(priv); + count = 0; + } + } } /* Backtrack one entry */ priv->rxq.read = i; - iwl_rx_queue_restock(priv); + iwl3945_rx_queue_restock(priv); } -int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl_tx_queue *txq) +/** + * iwl3945_tx_queue_update_write_ptr - Send new write index to hardware + */ +static int iwl3945_tx_queue_update_write_ptr(struct iwl3945_priv *priv, + struct iwl3945_tx_queue *txq) { u32 reg = 0; int rc = 0; @@ -4354,41 +4470,41 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, /* wake up nic if it's powered down ... * uCode will wake up, and interrupt us again, so next * time we'll skip this part. */ - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + reg = iwl3945_read32(priv, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg); - iwl_set_bit(priv, CSR_GP_CNTRL, + iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); return rc; } /* restore this queue's parameters in nic hardware. */ - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted(priv, HBUS_TARG_WRPTR, - txq->q.first_empty | (txq_id << 8)); - iwl_release_restricted_access(priv); + iwl3945_write_direct32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + iwl3945_release_nic_access(priv); /* else not in power-save mode, uCode will never sleep when we're * trying to tx (during RFKILL, we're not trying to tx). */ } else - iwl_write32(priv, HBUS_TARG_WRPTR, - txq->q.first_empty | (txq_id << 8)); + iwl3945_write32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); txq->need_update = 0; return rc; } -#ifdef CONFIG_IWLWIFI_DEBUG -static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) +#ifdef CONFIG_IWL3945_DEBUG +static void iwl3945_print_rx_config_cmd(struct iwl3945_rxon_cmd *rxon) { DECLARE_MAC_BUF(mac); IWL_DEBUG_RADIO("RX CONFIG:\n"); - iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); + iwl3945_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", @@ -4405,24 +4521,24 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) } #endif -static void iwl_enable_interrupts(struct iwl_priv *priv) +static void iwl3945_enable_interrupts(struct iwl3945_priv *priv) { IWL_DEBUG_ISR("Enabling interrupts\n"); set_bit(STATUS_INT_ENABLED, &priv->status); - iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); + iwl3945_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); } -static inline void iwl_disable_interrupts(struct iwl_priv *priv) +static inline void iwl3945_disable_interrupts(struct iwl3945_priv *priv) { clear_bit(STATUS_INT_ENABLED, &priv->status); /* disable interrupts from uCode/NIC to host */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); + iwl3945_write32(priv, CSR_INT_MASK, 0x00000000); /* acknowledge/clear/reset any interrupts still pending * from uCode or flow handler (Rx/Tx DMA) */ - iwl_write32(priv, CSR_INT, 0xffffffff); - iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); + iwl3945_write32(priv, CSR_INT, 0xffffffff); + iwl3945_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); IWL_DEBUG_ISR("Disabled interrupts\n"); } @@ -4449,7 +4565,7 @@ static const char *desc_lookup(int i) #define ERROR_START_OFFSET (1 * sizeof(u32)) #define ERROR_ELEM_SIZE (7 * sizeof(u32)) -static void iwl_dump_nic_error_log(struct iwl_priv *priv) +static void iwl3945_dump_nic_error_log(struct iwl3945_priv *priv) { u32 i; u32 desc, time, count, base, data1; @@ -4458,18 +4574,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) base = le32_to_cpu(priv->card_alive.error_event_table_ptr); - if (!iwl_hw_valid_rtc_data_addr(base)) { + if (!iwl3945_hw_valid_rtc_data_addr(base)) { IWL_ERROR("Not valid error log pointer 0x%08X\n", base); return; } - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } - count = iwl_read_restricted_mem(priv, base); + count = iwl3945_read_targ_mem(priv, base); if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { IWL_ERROR("Start IWL Error Log Dump:\n"); @@ -4482,19 +4598,19 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) for (i = ERROR_START_OFFSET; i < (count * ERROR_ELEM_SIZE) + ERROR_START_OFFSET; i += ERROR_ELEM_SIZE) { - desc = iwl_read_restricted_mem(priv, base + i); + desc = iwl3945_read_targ_mem(priv, base + i); time = - iwl_read_restricted_mem(priv, base + i + 1 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 1 * sizeof(u32)); blink1 = - iwl_read_restricted_mem(priv, base + i + 2 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 2 * sizeof(u32)); blink2 = - iwl_read_restricted_mem(priv, base + i + 3 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 3 * sizeof(u32)); ilink1 = - iwl_read_restricted_mem(priv, base + i + 4 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 4 * sizeof(u32)); ilink2 = - iwl_read_restricted_mem(priv, base + i + 5 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 5 * sizeof(u32)); data1 = - iwl_read_restricted_mem(priv, base + i + 6 * sizeof(u32)); + iwl3945_read_targ_mem(priv, base + i + 6 * sizeof(u32)); IWL_ERROR ("%-13s (#%d) %010u 0x%05X 0x%05X 0x%05X 0x%05X %u\n\n", @@ -4502,18 +4618,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) ilink1, ilink2, data1); } - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } -#define EVENT_START_OFFSET (4 * sizeof(u32)) +#define EVENT_START_OFFSET (6 * sizeof(u32)) /** - * iwl_print_event_log - Dump error event log to syslog + * iwl3945_print_event_log - Dump error event log to syslog * - * NOTE: Must be called with iwl_grab_restricted_access() already obtained! + * NOTE: Must be called with iwl3945_grab_nic_access() already obtained! */ -static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, +static void iwl3945_print_event_log(struct iwl3945_priv *priv, u32 start_idx, u32 num_events, u32 mode) { u32 i; @@ -4537,21 +4653,21 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read_restricted_mem(priv, ptr); + ev = iwl3945_read_targ_mem(priv, ptr); ptr += sizeof(u32); - time = iwl_read_restricted_mem(priv, ptr); + time = iwl3945_read_targ_mem(priv, ptr); ptr += sizeof(u32); if (mode == 0) IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ else { - data = iwl_read_restricted_mem(priv, ptr); + data = iwl3945_read_targ_mem(priv, ptr); ptr += sizeof(u32); IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); } } } -static void iwl_dump_nic_event_log(struct iwl_priv *priv) +static void iwl3945_dump_nic_event_log(struct iwl3945_priv *priv) { int rc; u32 base; /* SRAM byte address of event log header */ @@ -4562,29 +4678,29 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv) u32 size; /* # entries that we'll print */ base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl_hw_valid_rtc_data_addr(base)) { + if (!iwl3945_hw_valid_rtc_data_addr(base)) { IWL_ERROR("Invalid event log pointer 0x%08X\n", base); return; } - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } /* event log header */ - capacity = iwl_read_restricted_mem(priv, base); - mode = iwl_read_restricted_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_read_restricted_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_read_restricted_mem(priv, base + (3 * sizeof(u32))); + capacity = iwl3945_read_targ_mem(priv, base); + mode = iwl3945_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl3945_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl3945_read_targ_mem(priv, base + (3 * sizeof(u32))); size = num_wraps ? capacity : next_entry; /* bail out if nothing in log */ if (size == 0) { IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); return; } @@ -4594,31 +4710,31 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv) /* if uCode has wrapped back to top of log, start at the oldest entry, * i.e the next one that uCode would fill. */ if (num_wraps) - iwl_print_event_log(priv, next_entry, + iwl3945_print_event_log(priv, next_entry, capacity - next_entry, mode); /* (then/else) start at top of log */ - iwl_print_event_log(priv, 0, next_entry, mode); + iwl3945_print_event_log(priv, 0, next_entry, mode); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } /** - * iwl_irq_handle_error - called for HW or SW error interrupt from card + * iwl3945_irq_handle_error - called for HW or SW error interrupt from card */ -static void iwl_irq_handle_error(struct iwl_priv *priv) +static void iwl3945_irq_handle_error(struct iwl3945_priv *priv) { - /* Set the FW error flag -- cleared on iwl_down */ + /* Set the FW error flag -- cleared on iwl3945_down */ set_bit(STATUS_FW_ERROR, &priv->status); /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->status); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_FW_ERRORS) { - iwl_dump_nic_error_log(priv); - iwl_dump_nic_event_log(priv); - iwl_print_rx_config_cmd(&priv->staging_rxon); +#ifdef CONFIG_IWL3945_DEBUG + if (iwl3945_debug_level & IWL_DL_FW_ERRORS) { + iwl3945_dump_nic_error_log(priv); + iwl3945_dump_nic_event_log(priv); + iwl3945_print_rx_config_cmd(&priv->staging_rxon); } #endif @@ -4632,7 +4748,7 @@ static void iwl_irq_handle_error(struct iwl_priv *priv) IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); - if (iwl_is_associated(priv)) { + if (iwl3945_is_associated(priv)) { memcpy(&priv->recovery_rxon, &priv->active_rxon, sizeof(priv->recovery_rxon)); priv->error_recovering = 1; @@ -4641,16 +4757,16 @@ static void iwl_irq_handle_error(struct iwl_priv *priv) } } -static void iwl_error_recovery(struct iwl_priv *priv) +static void iwl3945_error_recovery(struct iwl3945_priv *priv) { unsigned long flags; memcpy(&priv->staging_rxon, &priv->recovery_rxon, sizeof(priv->staging_rxon)); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); - iwl_add_station(priv, priv->bssid, 1, 0); + iwl3945_add_station(priv, priv->bssid, 1, 0); spin_lock_irqsave(&priv->lock, flags); priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); @@ -4658,12 +4774,12 @@ static void iwl_error_recovery(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void iwl_irq_tasklet(struct iwl_priv *priv) +static void iwl3945_irq_tasklet(struct iwl3945_priv *priv) { u32 inta, handled = 0; u32 inta_fh; unsigned long flags; -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL3945_DEBUG u32 inta_mask; #endif @@ -4672,18 +4788,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Ack/clear/reset pending uCode interrupts. * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); + inta = iwl3945_read32(priv, CSR_INT); + iwl3945_write32(priv, CSR_INT, inta); /* Ack/clear/reset pending flow-handler (DMA) interrupts. * Any new interrupts that happen after this, either while we're * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); + inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); + iwl3945_write32(priv, CSR_FH_INT_STATUS, inta_fh); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_ISR) { - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ +#ifdef CONFIG_IWL3945_DEBUG + if (iwl3945_debug_level & IWL_DL_ISR) { + /* just for debug */ + inta_mask = iwl3945_read32(priv, CSR_INT_MASK); IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); } @@ -4703,9 +4820,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) IWL_ERROR("Microcode HW error detected. Restarting.\n"); /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl3945_disable_interrupts(priv); - iwl_irq_handle_error(priv); + iwl3945_irq_handle_error(priv); handled |= CSR_INT_BIT_HW_ERR; @@ -4714,8 +4831,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) return; } -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { +#ifdef CONFIG_IWL3945_DEBUG + if (iwl3945_debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_MAC_CLK_ACTV) IWL_DEBUG_ISR("Microcode started or stopped.\n"); @@ -4731,7 +4848,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* HW RF KILL switch toggled (4965 only) */ if (inta & CSR_INT_BIT_RF_KILL) { int hw_rf_kill = 0; - if (!(iwl_read32(priv, CSR_GP_CNTRL) & + if (!(iwl3945_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; @@ -4742,7 +4859,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Queue restart only if RF_KILL switch was set to "kill" * when we loaded driver, and is now set to "enable". * After we're Alive, RF_KILL gets handled by - * iwl_rx_card_state_notif() */ + * iwl3945_rx_card_state_notif() */ if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) queue_work(priv->workqueue, &priv->restart); @@ -4759,20 +4876,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) if (inta & CSR_INT_BIT_SW_ERR) { IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", inta); - iwl_irq_handle_error(priv); + iwl3945_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } /* uCode wakes up after power-down sleep */ if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR("Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[0]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[1]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[2]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[3]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[4]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[5]); + iwl3945_rx_queue_update_write_ptr(priv, &priv->rxq); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[0]); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[1]); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[2]); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[3]); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[4]); + iwl3945_tx_queue_update_write_ptr(priv, &priv->txq[5]); handled |= CSR_INT_BIT_WAKEUP; } @@ -4781,19 +4898,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) * Rx "responses" (frame-received notification), and other * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl_rx_handle(priv); + iwl3945_rx_handle(priv); handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); } if (inta & CSR_INT_BIT_FH_TX) { IWL_DEBUG_ISR("Tx interrupt\n"); - iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted(priv, + iwl3945_write32(priv, CSR_FH_INT_STATUS, (1 << 6)); + if (!iwl3945_grab_nic_access(priv)) { + iwl3945_write_direct32(priv, FH_TCSR_CREDIT (ALM_FH_SRVC_CHNL), 0x0); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } handled |= CSR_INT_BIT_FH_TX; } @@ -4808,13 +4925,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) } /* Re-enable all interrupts */ - iwl_enable_interrupts(priv); + iwl3945_enable_interrupts(priv); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); +#ifdef CONFIG_IWL3945_DEBUG + if (iwl3945_debug_level & (IWL_DL_ISR)) { + inta = iwl3945_read32(priv, CSR_INT); + inta_mask = iwl3945_read32(priv, CSR_INT_MASK); + inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); } @@ -4822,9 +4939,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static irqreturn_t iwl_isr(int irq, void *data) +static irqreturn_t iwl3945_isr(int irq, void *data) { - struct iwl_priv *priv = data; + struct iwl3945_priv *priv = data; u32 inta, inta_mask; u32 inta_fh; if (!priv) @@ -4836,12 +4953,12 @@ static irqreturn_t iwl_isr(int irq, void *data) * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); + inta_mask = iwl3945_read32(priv, CSR_INT_MASK); /* just for debug */ + iwl3945_write32(priv, CSR_INT_MASK, 0x00000000); /* Discover which interrupts are active/pending */ - inta = iwl_read32(priv, CSR_INT); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + inta = iwl3945_read32(priv, CSR_INT); + inta_fh = iwl3945_read32(priv, CSR_FH_INT_STATUS); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, @@ -4860,7 +4977,7 @@ static irqreturn_t iwl_isr(int irq, void *data) IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); - /* iwl_irq_tasklet() will service interrupts and re-enable them */ + /* iwl3945_irq_tasklet() will service interrupts and re-enable them */ tasklet_schedule(&priv->irq_tasklet); unplugged: spin_unlock(&priv->lock); @@ -4869,18 +4986,18 @@ unplugged: none: /* re-enable interrupts here since we don't have anything to service. */ - iwl_enable_interrupts(priv); + iwl3945_enable_interrupts(priv); spin_unlock(&priv->lock); return IRQ_NONE; } /************************** EEPROM BANDS **************************** * - * The iwl_eeprom_band definitions below provide the mapping from the + * The iwl3945_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 + * For example, iwl3945_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. @@ -4906,58 +5023,58 @@ unplugged: *********************************************************************/ /* 2.4 GHz */ -static const u8 iwl_eeprom_band_1[14] = { +static const u8 iwl3945_eeprom_band_1[14] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; /* 5.2 GHz bands */ -static const u8 iwl_eeprom_band_2[] = { +static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */ 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 }; -static const u8 iwl_eeprom_band_3[] = { /* 5205-5320MHz */ +static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 }; -static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ +static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }; -static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ +static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */ 145, 149, 153, 157, 161, 165 }; -static void iwl_init_band_reference(const struct iwl_priv *priv, int band, +static void iwl3945_init_band_reference(const struct iwl3945_priv *priv, int band, int *eeprom_ch_count, - const struct iwl_eeprom_channel + const struct iwl3945_eeprom_channel **eeprom_ch_info, const u8 **eeprom_ch_index) { switch (band) { case 1: /* 2.4GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); + *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1); *eeprom_ch_info = priv->eeprom.band_1_channels; - *eeprom_ch_index = iwl_eeprom_band_1; + *eeprom_ch_index = iwl3945_eeprom_band_1; break; - case 2: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); + case 2: /* 4.9GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2); *eeprom_ch_info = priv->eeprom.band_2_channels; - *eeprom_ch_index = iwl_eeprom_band_2; + *eeprom_ch_index = iwl3945_eeprom_band_2; break; case 3: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); + *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3); *eeprom_ch_info = priv->eeprom.band_3_channels; - *eeprom_ch_index = iwl_eeprom_band_3; + *eeprom_ch_index = iwl3945_eeprom_band_3; break; - case 4: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); + case 4: /* 5.5GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4); *eeprom_ch_info = priv->eeprom.band_4_channels; - *eeprom_ch_index = iwl_eeprom_band_4; + *eeprom_ch_index = iwl3945_eeprom_band_4; break; - case 5: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); + case 5: /* 5.7GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5); *eeprom_ch_info = priv->eeprom.band_5_channels; - *eeprom_ch_index = iwl_eeprom_band_5; + *eeprom_ch_index = iwl3945_eeprom_band_5; break; default: BUG(); @@ -4965,7 +5082,12 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, int band, } } -const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, +/** + * iwl3945_get_channel_info - Find driver's private channel info + * + * Based on band and channel number. + */ +const struct iwl3945_channel_info *iwl3945_get_channel_info(const struct iwl3945_priv *priv, int phymode, u16 channel) { int i; @@ -4992,13 +5114,16 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") -static int iwl_init_channel_map(struct iwl_priv *priv) +/** + * iwl3945_init_channel_map - Set up driver's info for all possible channels + */ +static int iwl3945_init_channel_map(struct iwl3945_priv *priv) { int eeprom_ch_count = 0; const u8 *eeprom_ch_index = NULL; - const struct iwl_eeprom_channel *eeprom_ch_info = NULL; + const struct iwl3945_eeprom_channel *eeprom_ch_info = NULL; int band, ch; - struct iwl_channel_info *ch_info; + struct iwl3945_channel_info *ch_info; if (priv->channel_count) { IWL_DEBUG_INFO("Channel map already initialized.\n"); @@ -5014,15 +5139,15 @@ static int iwl_init_channel_map(struct iwl_priv *priv) IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n"); priv->channel_count = - ARRAY_SIZE(iwl_eeprom_band_1) + - ARRAY_SIZE(iwl_eeprom_band_2) + - ARRAY_SIZE(iwl_eeprom_band_3) + - ARRAY_SIZE(iwl_eeprom_band_4) + - ARRAY_SIZE(iwl_eeprom_band_5); + ARRAY_SIZE(iwl3945_eeprom_band_1) + + ARRAY_SIZE(iwl3945_eeprom_band_2) + + ARRAY_SIZE(iwl3945_eeprom_band_3) + + ARRAY_SIZE(iwl3945_eeprom_band_4) + + ARRAY_SIZE(iwl3945_eeprom_band_5); IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count); - priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * + priv->channel_info = kzalloc(sizeof(struct iwl3945_channel_info) * priv->channel_count, GFP_KERNEL); if (!priv->channel_info) { IWL_ERROR("Could not allocate channel_info\n"); @@ -5037,7 +5162,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv) * what just in the EEPROM) */ for (band = 1; band <= 5; band++) { - iwl_init_band_reference(priv, band, &eeprom_ch_count, + iwl3945_init_band_reference(priv, band, &eeprom_ch_count, &eeprom_ch_info, &eeprom_ch_index); /* Loop through each band adding each of the channels */ @@ -5101,6 +5226,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv) } } + /* Set up txpower settings in driver for all channels */ if (iwl3945_txpower_set_from_eeprom(priv)) return -EIO; @@ -5130,7 +5256,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv) #define IWL_PASSIVE_DWELL_BASE (100) #define IWL_CHANNEL_TUNE_TIME 5 -static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode) +static inline u16 iwl3945_get_active_dwell_time(struct iwl3945_priv *priv, int phymode) { if (phymode == MODE_IEEE80211A) return IWL_ACTIVE_DWELL_TIME_52; @@ -5138,14 +5264,14 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode) return IWL_ACTIVE_DWELL_TIME_24; } -static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode) +static u16 iwl3945_get_passive_dwell_time(struct iwl3945_priv *priv, int phymode) { - u16 active = iwl_get_active_dwell_time(priv, phymode); + u16 active = iwl3945_get_active_dwell_time(priv, phymode); u16 passive = (phymode != MODE_IEEE80211A) ? IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - if (iwl_is_associated(priv)) { + if (iwl3945_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) */ @@ -5161,30 +5287,30 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode) return passive; } -static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, +static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, int phymode, u8 is_active, u8 direct_mask, - struct iwl_scan_channel *scan_ch) + struct iwl3945_scan_channel *scan_ch) { const struct ieee80211_channel *channels = NULL; const struct ieee80211_hw_mode *hw_mode; - const struct iwl_channel_info *ch_info; + const struct iwl3945_channel_info *ch_info; u16 passive_dwell = 0; u16 active_dwell = 0; int added, i; - hw_mode = iwl_get_hw_mode(priv, phymode); + hw_mode = iwl3945_get_hw_mode(priv, phymode); if (!hw_mode) return 0; channels = hw_mode->channels; - active_dwell = iwl_get_active_dwell_time(priv, phymode); - passive_dwell = iwl_get_passive_dwell_time(priv, phymode); + active_dwell = iwl3945_get_active_dwell_time(priv, phymode); + passive_dwell = iwl3945_get_passive_dwell_time(priv, phymode); for (i = 0, added = 0; i < hw_mode->num_channels; i++) { if (channels[i].chan == le16_to_cpu(priv->active_rxon.channel)) { - if (iwl_is_associated(priv)) { + if (iwl3945_is_associated(priv)) { IWL_DEBUG_SCAN ("Skipping current channel %d\n", le16_to_cpu(priv->active_rxon.channel)); @@ -5195,7 +5321,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, scan_ch->channel = channels[i].chan; - ch_info = iwl_get_channel_info(priv, phymode, scan_ch->channel); + ch_info = iwl3945_get_channel_info(priv, phymode, scan_ch->channel); if (!is_channel_valid(ch_info)) { IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", scan_ch->channel); @@ -5217,7 +5343,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, scan_ch->active_dwell = cpu_to_le16(active_dwell); scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set power levels to defaults */ + /* Set txpower levels to defaults */ scan_ch->tpc.dsp_atten = 110; /* scan_pwr_info->tpc.dsp_atten; */ @@ -5227,8 +5353,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, else { scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level - scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3; + * power level: + * scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3; */ } @@ -5246,7 +5372,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, return added; } -static void iwl_reset_channel_flag(struct iwl_priv *priv) +static void iwl3945_reset_channel_flag(struct iwl3945_priv *priv) { int i, j; for (i = 0; i < 3; i++) { @@ -5256,13 +5382,13 @@ static void iwl_reset_channel_flag(struct iwl_priv *priv) } } -static void iwl_init_hw_rates(struct iwl_priv *priv, +static void iwl3945_init_hw_rates(struct iwl3945_priv *priv, struct ieee80211_rate *rates) { int i; for (i = 0; i < IWL_RATE_COUNT; i++) { - rates[i].rate = iwl_rates[i].ieee * 5; + rates[i].rate = iwl3945_rates[i].ieee * 5; rates[i].val = i; /* Rate scaling will work on indexes */ rates[i].val2 = i; rates[i].flags = IEEE80211_RATE_SUPPORTED; @@ -5274,7 +5400,7 @@ static void iwl_init_hw_rates(struct iwl_priv *priv, * If CCK 1M then set rate flag to CCK else CCK_2 * which is CCK | PREAMBLE2 */ - rates[i].flags |= (iwl_rates[i].plcp == 10) ? + rates[i].flags |= (iwl3945_rates[i].plcp == 10) ? IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; } @@ -5285,11 +5411,11 @@ static void iwl_init_hw_rates(struct iwl_priv *priv, } /** - * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom + * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom */ -static int iwl_init_geos(struct iwl_priv *priv) +static int iwl3945_init_geos(struct iwl3945_priv *priv) { - struct iwl_channel_info *ch; + struct iwl3945_channel_info *ch; struct ieee80211_hw_mode *modes; struct ieee80211_channel *channels; struct ieee80211_channel *geo_ch; @@ -5335,7 +5461,7 @@ static int iwl_init_geos(struct iwl_priv *priv) /* 5.2GHz channels start after the 2.4GHz channels */ modes[A].mode = MODE_IEEE80211A; - modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; + modes[A].channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)]; modes[A].rates = &rates[4]; modes[A].num_rates = 8; /* just OFDM */ modes[A].num_channels = 0; @@ -5355,7 +5481,7 @@ static int iwl_init_geos(struct iwl_priv *priv) priv->ieee_channels = channels; priv->ieee_rates = rates; - iwl_init_hw_rates(priv, rates); + iwl3945_init_hw_rates(priv, rates); for (i = 0, geo_ch = channels; i < priv->channel_count; i++) { ch = &priv->channel_info[i]; @@ -5438,7 +5564,7 @@ static int iwl_init_geos(struct iwl_priv *priv) * ******************************************************************************/ -static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) +static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv) { if (priv->ucode_code.v_addr != NULL) { pci_free_consistent(priv->pci_dev, @@ -5485,10 +5611,10 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) } /** - * iwl_verify_inst_full - verify runtime uCode image in card vs. host, + * iwl3945_verify_inst_full - verify runtime uCode image in card vs. host, * looking at all data. */ -static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) +static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len) { u32 val; u32 save_len = len; @@ -5497,18 +5623,18 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) IWL_DEBUG_INFO("ucode inst image size is %u\n", len); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); + iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); errcnt = 0; for (; len > 0; len -= sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT); + val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { IWL_ERROR("uCode INST section is invalid at " "offset 0x%x, is 0x%x, s/b 0x%x\n", @@ -5520,22 +5646,21 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) } } - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); if (!errcnt) - IWL_DEBUG_INFO - ("ucode image in INSTRUCTION memory is good\n"); + IWL_DEBUG_INFO("ucode image in INSTRUCTION memory is good\n"); return rc; } /** - * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, + * iwl3945_verify_inst_sparse - verify runtime uCode image in card vs. host, * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +static int iwl3945_verify_inst_sparse(struct iwl3945_priv *priv, __le32 *image, u32 len) { u32 val; int rc = 0; @@ -5544,7 +5669,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) IWL_DEBUG_INFO("ucode inst image size is %u\n", len); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) return rc; @@ -5552,9 +5677,9 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, + iwl3945_write_direct32(priv, HBUS_TARG_MEM_RADDR, i + RTC_INST_LOWER_BOUND); - val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT); + val = _iwl3945_read_direct32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { #if 0 /* Enable this if you want to see details */ IWL_ERROR("uCode INST section is invalid at " @@ -5568,17 +5693,17 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) } } - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); return rc; } /** - * iwl_verify_ucode - determine which instruction image is in SRAM, + * iwl3945_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -static int iwl_verify_ucode(struct iwl_priv *priv) +static int iwl3945_verify_ucode(struct iwl3945_priv *priv) { __le32 *image; u32 len; @@ -5587,7 +5712,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try bootstrap */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl3945_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n"); return 0; @@ -5596,7 +5721,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try initialize */ image = (__le32 *)priv->ucode_init.v_addr; len = priv->ucode_init.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl3945_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n"); return 0; @@ -5605,7 +5730,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try runtime/protocol */ image = (__le32 *)priv->ucode_code.v_addr; len = priv->ucode_code.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl3945_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n"); return 0; @@ -5613,18 +5738,19 @@ static int iwl_verify_ucode(struct iwl_priv *priv) IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - /* Show first several data entries in instruction SRAM. - * Selection of bootstrap image is arbitrary. */ + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - rc = iwl_verify_inst_full(priv, image, len); + rc = iwl3945_verify_inst_full(priv, image, len); return rc; } /* check contents of special bootstrap uCode SRAM */ -static int iwl_verify_bsm(struct iwl_priv *priv) +static int iwl3945_verify_bsm(struct iwl3945_priv *priv) { __le32 *image = priv->ucode_boot.v_addr; u32 len = priv->ucode_boot.len; @@ -5634,11 +5760,11 @@ static int iwl_verify_bsm(struct iwl_priv *priv) IWL_DEBUG_INFO("Begin verify bsm\n"); /* verify BSM SRAM contents */ - val = iwl_read_restricted_reg(priv, BSM_WR_DWCOUNT_REG); + val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG); for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len; reg += sizeof(u32), image ++) { - val = iwl_read_restricted_reg(priv, reg); + val = iwl3945_read_prph(priv, reg); if (val != le32_to_cpu(*image)) { IWL_ERROR("BSM uCode verification failed at " "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", @@ -5655,7 +5781,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv) } /** - * iwl_load_bsm - Load bootstrap instructions + * iwl3945_load_bsm - Load bootstrap instructions * * BSM operation: * @@ -5686,7 +5812,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv) * the runtime uCode instructions and the backup data cache into SRAM, * and re-launches the runtime uCode from where it left off. */ -static int iwl_load_bsm(struct iwl_priv *priv) +static int iwl3945_load_bsm(struct iwl3945_priv *priv) { __le32 *image = priv->ucode_boot.v_addr; u32 len = priv->ucode_boot.len; @@ -5706,8 +5832,8 @@ static int iwl_load_bsm(struct iwl_priv *priv) return -EINVAL; /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... bits 31:0 for 3945, bits 35:4 for 4965. - * NOTE: iwl_initialize_alive_start() will replace these values, + * in host DRAM ... host DRAM physical address bits 31:0 for 3945. + * NOTE: iwl3945_initialize_alive_start() will replace these values, * after the "initialize" uCode has run, to point to * runtime/protocol instructions and backup data cache. */ pinst = priv->ucode_init.p_addr; @@ -5715,42 +5841,42 @@ static int iwl_load_bsm(struct iwl_priv *priv) inst_len = priv->ucode_init.len; data_len = priv->ucode_init_data.len; - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); /* Fill BSM memory with bootstrap instructions */ for (reg_offset = BSM_SRAM_LOWER_BOUND; reg_offset < BSM_SRAM_LOWER_BOUND + len; reg_offset += sizeof(u32), image++) - _iwl_write_restricted_reg(priv, reg_offset, + _iwl3945_write_prph(priv, reg_offset, le32_to_cpu(*image)); - rc = iwl_verify_bsm(priv); + rc = iwl3945_verify_bsm(priv); if (rc) { - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); return rc; } /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_restricted_reg(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_restricted_reg(priv, BSM_WR_MEM_DST_REG, + iwl3945_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl3945_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND); - iwl_write_restricted_reg(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + iwl3945_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); /* Load bootstrap code into instruction SRAM now, * to prepare to load "initialize" uCode */ - iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG, + iwl3945_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); /* Wait for load of bootstrap uCode to finish */ for (i = 0; i < 100; i++) { - done = iwl_read_restricted_reg(priv, BSM_WR_CTRL_REG); + done = iwl3945_read_prph(priv, BSM_WR_CTRL_REG); if (!(done & BSM_WR_CTRL_REG_BIT_START)) break; udelay(10); @@ -5764,29 +5890,35 @@ static int iwl_load_bsm(struct iwl_priv *priv) /* Enable future boot loads whenever power management unit triggers it * (e.g. when powering back up after power-save shutdown) */ - iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG, + iwl3945_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); return 0; } -static void iwl_nic_start(struct iwl_priv *priv) +static void iwl3945_nic_start(struct iwl3945_priv *priv) { /* Remove all resets to allow NIC to operate */ - iwl_write32(priv, CSR_RESET, 0); + iwl3945_write32(priv, CSR_RESET, 0); +} + +static int iwl3945_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) +{ + desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); + return (desc->v_addr != NULL) ? 0 : -ENOMEM; } /** - * iwl_read_ucode - Read uCode images from disk file. + * iwl3945_read_ucode - Read uCode images from disk file. * * Copy into buffers for card to fetch via bus-mastering */ -static int iwl_read_ucode(struct iwl_priv *priv) +static int iwl3945_read_ucode(struct iwl3945_priv *priv) { - struct iwl_ucode *ucode; - int rc = 0; + struct iwl3945_ucode *ucode; + int ret = 0; const struct firmware *ucode_raw; /* firmware file name contains uCode/driver compatibility version */ const char *name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode"; @@ -5796,9 +5928,10 @@ static int iwl_read_ucode(struct iwl_priv *priv) /* Ask kernel firmware_class module to get the boot firmware off disk. * request_firmware() is synchronous, file is in memory on return. */ - rc = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); - if (rc < 0) { - IWL_ERROR("%s firmware file req failed: Reason %d\n", name, rc); + ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); + if (ret < 0) { + IWL_ERROR("%s firmware file req failed: Reason %d\n", + name, ret); goto error; } @@ -5808,7 +5941,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) /* Make sure that we got at least our header! */ if (ucode_raw->size < sizeof(*ucode)) { IWL_ERROR("File size way too small!\n"); - rc = -EINVAL; + ret = -EINVAL; goto err_release; } @@ -5823,16 +5956,11 @@ static int iwl_read_ucode(struct iwl_priv *priv) boot_size = le32_to_cpu(ucode->boot_size); IWL_DEBUG_INFO("f/w package hdr ucode version = 0x%x\n", ver); - IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", - inst_size); - IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", - data_size); - IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", - init_size); - IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", - init_data_size); - IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", - boot_size); + IWL_DEBUG_INFO("f/w package hdr runtime inst size = %u\n", inst_size); + IWL_DEBUG_INFO("f/w package hdr runtime data size = %u\n", data_size); + IWL_DEBUG_INFO("f/w package hdr init inst size = %u\n", init_size); + IWL_DEBUG_INFO("f/w package hdr init data size = %u\n", init_data_size); + IWL_DEBUG_INFO("f/w package hdr boot inst size = %u\n", boot_size); /* Verify size of file vs. image size info in file's header */ if (ucode_raw->size < sizeof(*ucode) + @@ -5841,43 +5969,40 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_DEBUG_INFO("uCode file size %d too small\n", (int)ucode_raw->size); - rc = -EINVAL; + ret = -EINVAL; goto err_release; } /* Verify that uCode images will fit in card's SRAM */ if (inst_size > IWL_MAX_INST_SIZE) { - IWL_DEBUG_INFO("uCode instr len %d too large to fit in card\n", - (int)inst_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", + inst_size); + ret = -EINVAL; goto err_release; } if (data_size > IWL_MAX_DATA_SIZE) { - IWL_DEBUG_INFO("uCode data len %d too large to fit in card\n", - (int)data_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", + data_size); + ret = -EINVAL; goto err_release; } if (init_size > IWL_MAX_INST_SIZE) { - IWL_DEBUG_INFO - ("uCode init instr len %d too large to fit in card\n", - (int)init_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode init instr len %d too large to fit in\n", + init_size); + ret = -EINVAL; goto err_release; } if (init_data_size > IWL_MAX_DATA_SIZE) { - IWL_DEBUG_INFO - ("uCode init data len %d too large to fit in card\n", - (int)init_data_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode init data len %d too large to fit in\n", + init_data_size); + ret = -EINVAL; goto err_release; } if (boot_size > IWL_MAX_BSM_SIZE) { - IWL_DEBUG_INFO - ("uCode boot instr len %d too large to fit in bsm\n", - (int)boot_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode boot instr len %d too large to fit in\n", + boot_size); + ret = -EINVAL; goto err_release; } @@ -5887,66 +6012,54 @@ static int iwl_read_ucode(struct iwl_priv *priv) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ priv->ucode_code.len = inst_size; - priv->ucode_code.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_code.len, - &(priv->ucode_code.p_addr)); + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); priv->ucode_data.len = data_size; - priv->ucode_data.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_data.len, - &(priv->ucode_data.p_addr)); + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); priv->ucode_data_backup.len = data_size; - priv->ucode_data_backup.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_data_backup.len, - &(priv->ucode_data_backup.p_addr)); + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); + if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || + !priv->ucode_data_backup.v_addr) + goto err_pci_alloc; /* Initialization instructions and data */ - priv->ucode_init.len = init_size; - priv->ucode_init.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_init.len, - &(priv->ucode_init.p_addr)); - - priv->ucode_init_data.len = init_data_size; - priv->ucode_init_data.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_init_data.len, - &(priv->ucode_init_data.p_addr)); + if (init_size && init_data_size) { + priv->ucode_init.len = init_size; + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = init_data_size; + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); + + if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + } /* Bootstrap (instructions only, no data) */ - priv->ucode_boot.len = boot_size; - priv->ucode_boot.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_boot.len, - &(priv->ucode_boot.p_addr)); + if (boot_size) { + priv->ucode_boot.len = boot_size; + iwl3945_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); - if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr || - !priv->ucode_boot.v_addr || !priv->ucode_data_backup.v_addr) - goto err_pci_alloc; + if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + } /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ src = &ucode->data[0]; len = priv->ucode_code.len; - IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len); memcpy(priv->ucode_code.v_addr, src, len); IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); /* Runtime data (2nd block) - * NOTE: Copy into backup buffer will be done in iwl_up() */ + * NOTE: Copy into backup buffer will be done in iwl3945_up() */ src = &ucode->data[inst_size]; len = priv->ucode_data.len; - IWL_DEBUG_INFO("Copying (but not loading) uCode data len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len); memcpy(priv->ucode_data.v_addr, src, len); memcpy(priv->ucode_data_backup.v_addr, src, len); @@ -5954,8 +6067,8 @@ static int iwl_read_ucode(struct iwl_priv *priv) if (init_size) { src = &ucode->data[inst_size + data_size]; len = priv->ucode_init.len; - IWL_DEBUG_INFO("Copying (but not loading) init instr len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n", + len); memcpy(priv->ucode_init.v_addr, src, len); } @@ -5981,19 +6094,19 @@ static int iwl_read_ucode(struct iwl_priv *priv) err_pci_alloc: IWL_ERROR("failed to allocate pci memory\n"); - rc = -ENOMEM; - iwl_dealloc_ucode_pci(priv); + ret = -ENOMEM; + iwl3945_dealloc_ucode_pci(priv); err_release: release_firmware(ucode_raw); error: - return rc; + return ret; } /** - * iwl_set_ucode_ptrs - Set uCode address location + * iwl3945_set_ucode_ptrs - Set uCode address location * * Tell initialization uCode where to find runtime uCode. * @@ -6001,7 +6114,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) * We need to replace them to load runtime uCode inst and data, * and to save runtime data when powering down. */ -static int iwl_set_ucode_ptrs(struct iwl_priv *priv) +static int iwl3945_set_ucode_ptrs(struct iwl3945_priv *priv) { dma_addr_t pinst; dma_addr_t pdata; @@ -6013,24 +6126,24 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) pdata = priv->ucode_data_backup.p_addr; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } /* Tell bootstrap uCode where to find image to load */ - iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + iwl3945_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl3945_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl3945_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, priv->ucode_data.len); /* Inst bytecount must be last to set up, bit 31 signals uCode * that all new ptr/size info is in place */ - iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, + iwl3945_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, priv->ucode_code.len | BSM_DRAM_INST_LOAD); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); @@ -6040,17 +6153,13 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) } /** - * iwl_init_alive_start - Called after REPLY_ALIVE notification receieved + * iwl3945_init_alive_start - Called after REPLY_ALIVE notification received * * Called after REPLY_ALIVE notification received from "initialize" uCode. * - * The 4965 "initialize" ALIVE reply contains calibration data for: - * Voltage, temperature, and MIMO tx gain correction, now stored in priv - * (3945 does not contain this data). - * * Tell "initialize" uCode to go ahead and load the runtime uCode. -*/ -static void iwl_init_alive_start(struct iwl_priv *priv) + */ +static void iwl3945_init_alive_start(struct iwl3945_priv *priv) { /* Check alive response for "valid" sign from uCode */ if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { @@ -6063,7 +6172,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv) /* Bootstrap uCode has loaded initialize uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl3945_verify_ucode(priv)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); @@ -6074,7 +6183,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv) * load and launch runtime uCode, which will send us another "Alive" * notification. */ IWL_DEBUG_INFO("Initialization Alive received.\n"); - if (iwl_set_ucode_ptrs(priv)) { + if (iwl3945_set_ucode_ptrs(priv)) { /* Runtime instruction load won't happen; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); @@ -6088,11 +6197,11 @@ static void iwl_init_alive_start(struct iwl_priv *priv) /** - * iwl_alive_start - called after REPLY_ALIVE notification received + * iwl3945_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's - * Alive gets handled by iwl_init_alive_start()). + * Alive gets handled by iwl3945_init_alive_start()). */ -static void iwl_alive_start(struct iwl_priv *priv) +static void iwl3945_alive_start(struct iwl3945_priv *priv) { int rc = 0; int thermal_spin = 0; @@ -6110,30 +6219,30 @@ static void iwl_alive_start(struct iwl_priv *priv) /* Initialize uCode has loaded Runtime uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "runtime" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl3945_verify_ucode(priv)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Bad runtime uCode load.\n"); goto restart; } - iwl_clear_stations_table(priv); + iwl3945_clear_stations_table(priv); - rc = iwl_grab_restricted_access(priv); + rc = iwl3945_grab_nic_access(priv); if (rc) { IWL_WARNING("Can not read rfkill status from adapter\n"); return; } - rfkill = iwl_read_restricted_reg(priv, APMG_RFKILL_REG); + rfkill = iwl3945_read_prph(priv, APMG_RFKILL_REG); IWL_DEBUG_INFO("RFKILL status: 0x%x\n", rfkill); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); if (rfkill & 0x1) { clear_bit(STATUS_RF_KILL_HW, &priv->status); /* if rfkill is not on, then wait for thermal * sensor in adapter to kick in */ - while (iwl_hw_get_temperature(priv) == 0) { + while (iwl3945_hw_get_temperature(priv) == 0) { thermal_spin++; udelay(10); } @@ -6144,28 +6253,28 @@ static void iwl_alive_start(struct iwl_priv *priv) } else set_bit(STATUS_RF_KILL_HW, &priv->status); - /* After the ALIVE response, we can process host commands */ + /* After the ALIVE response, we can send commands to 3945 uCode */ set_bit(STATUS_ALIVE, &priv->status); /* Clear out the uCode error bit if it is set */ clear_bit(STATUS_FW_ERROR, &priv->status); - rc = iwl_init_channel_map(priv); + rc = iwl3945_init_channel_map(priv); if (rc) { IWL_ERROR("initializing regulatory failed: %d\n", rc); return; } - iwl_init_geos(priv); + iwl3945_init_geos(priv); - if (iwl_is_rfkill(priv)) + if (iwl3945_is_rfkill(priv)) return; if (!priv->mac80211_registered) { /* Unlock so any user space entry points can call back into * the driver without a deadlock... */ mutex_unlock(&priv->mutex); - iwl_rate_control_register(priv->hw); + iwl3945_rate_control_register(priv->hw); rc = ieee80211_register_hw(priv->hw); priv->hw->conf.beacon_int = 100; mutex_lock(&priv->mutex); @@ -6178,33 +6287,33 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->mac80211_registered = 1; - iwl_reset_channel_flag(priv); + iwl3945_reset_channel_flag(priv); } else ieee80211_start_queues(priv->hw); priv->active_rate = priv->rates_mask; priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; - iwl_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); + iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); - if (iwl_is_associated(priv)) { - struct iwl_rxon_cmd *active_rxon = - (struct iwl_rxon_cmd *)(&priv->active_rxon); + if (iwl3945_is_associated(priv)) { + struct iwl3945_rxon_cmd *active_rxon = + (struct iwl3945_rxon_cmd *)(&priv->active_rxon); memcpy(&priv->staging_rxon, &priv->active_rxon, sizeof(priv->staging_rxon)); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv); + iwl3945_connection_init_rx_config(priv); memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); } - /* Configure BT coexistence */ - iwl_send_bt_config(priv); + /* Configure Bluetooth device coexistence support */ + iwl3945_send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); /* At this point, the NIC is initialized and operational */ priv->notif_missed_beacons = 0; @@ -6215,7 +6324,7 @@ static void iwl_alive_start(struct iwl_priv *priv) IWL_DEBUG_INFO("ALIVE processing complete.\n"); if (priv->error_recovering) - iwl_error_recovery(priv); + iwl3945_error_recovery(priv); return; @@ -6223,9 +6332,9 @@ static void iwl_alive_start(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv); +static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv); -static void __iwl_down(struct iwl_priv *priv) +static void __iwl3945_down(struct iwl3945_priv *priv) { unsigned long flags; int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); @@ -6238,12 +6347,12 @@ static void __iwl_down(struct iwl_priv *priv) if (!exit_pending) set_bit(STATUS_EXIT_PENDING, &priv->status); - iwl_clear_stations_table(priv); + iwl3945_clear_stations_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); - iwl_cancel_deferred_work(priv); + iwl3945_cancel_deferred_work(priv); /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ @@ -6251,17 +6360,17 @@ static void __iwl_down(struct iwl_priv *priv) clear_bit(STATUS_EXIT_PENDING, &priv->status); /* stop and reset the on-board processor */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl3945_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); /* tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl3945_disable_interrupts(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); - /* If we have not previously called iwl_init() then + /* If we have not previously called iwl3945_init() then * clear all bits but the RF Kill and SUSPEND bits and return */ - if (!iwl_is_init(priv)) { + if (!iwl3945_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << @@ -6283,47 +6392,47 @@ static void __iwl_down(struct iwl_priv *priv) STATUS_FW_ERROR; spin_lock_irqsave(&priv->lock, flags); - iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); spin_unlock_irqrestore(&priv->lock, flags); - iwl_hw_txq_ctx_stop(priv); - iwl_hw_rxq_stop(priv); + iwl3945_hw_txq_ctx_stop(priv); + iwl3945_hw_rxq_stop(priv); spin_lock_irqsave(&priv->lock, flags); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG, + if (!iwl3945_grab_nic_access(priv)) { + iwl3945_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } spin_unlock_irqrestore(&priv->lock, flags); udelay(5); - iwl_hw_nic_stop_master(priv); - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - iwl_hw_nic_reset(priv); + iwl3945_hw_nic_stop_master(priv); + iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl3945_hw_nic_reset(priv); exit: - memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); + memset(&priv->card_alive, 0, sizeof(struct iwl3945_alive_resp)); if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = NULL; /* clear out any free frames */ - iwl_clear_free_frames(priv); + iwl3945_clear_free_frames(priv); } -static void iwl_down(struct iwl_priv *priv) +static void iwl3945_down(struct iwl3945_priv *priv) { mutex_lock(&priv->mutex); - __iwl_down(priv); + __iwl3945_down(priv); mutex_unlock(&priv->mutex); } #define MAX_HW_RESTARTS 5 -static int __iwl_up(struct iwl_priv *priv) +static int __iwl3945_up(struct iwl3945_priv *priv) { DECLARE_MAC_BUF(mac); int rc, i; @@ -6339,26 +6448,26 @@ static int __iwl_up(struct iwl_priv *priv) return 0; } - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); - rc = iwl_hw_nic_init(priv); + rc = iwl3945_hw_nic_init(priv); if (rc) { IWL_ERROR("Unable to int nic\n"); return rc; } /* make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); /* clear (again), then enable host interrupts */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_enable_interrupts(priv); + iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl3945_enable_interrupts(priv); /* really make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Copy original ucode data image from disk into backup cache. * This will be used to initialize the on-board processor's @@ -6368,12 +6477,12 @@ static int __iwl_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl_clear_stations_table(priv); + iwl3945_clear_stations_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - rc = iwl_load_bsm(priv); + rc = iwl3945_load_bsm(priv); if (rc) { IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); @@ -6381,9 +6490,9 @@ static int __iwl_up(struct iwl_priv *priv) } /* start card; "initialize" will load runtime ucode */ - iwl_nic_start(priv); + iwl3945_nic_start(priv); - /* MAC Address location in EEPROM same for 3945/4965 */ + /* MAC Address location in EEPROM is same for 3945/4965 */ get_eeprom_mac(priv, priv->mac_addr); IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); @@ -6396,7 +6505,7 @@ static int __iwl_up(struct iwl_priv *priv) } set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); + __iwl3945_down(priv); /* tried to restart and config the device for as long as our * patience could withstand */ @@ -6411,35 +6520,35 @@ static int __iwl_up(struct iwl_priv *priv) * *****************************************************************************/ -static void iwl_bg_init_alive_start(struct work_struct *data) +static void iwl3945_bg_init_alive_start(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, init_alive_start.work); + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, init_alive_start.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_init_alive_start(priv); + iwl3945_init_alive_start(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_alive_start(struct work_struct *data) +static void iwl3945_bg_alive_start(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, alive_start.work); + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, alive_start.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_alive_start(priv); + iwl3945_alive_start(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_rf_kill(struct work_struct *work) +static void iwl3945_bg_rf_kill(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); + struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, rf_kill); wake_up_interruptible(&priv->wait_command_queue); @@ -6448,7 +6557,7 @@ static void iwl_bg_rf_kill(struct work_struct *work) mutex_lock(&priv->mutex); - if (!iwl_is_rfkill(priv)) { + if (!iwl3945_is_rfkill(priv)) { IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, "HW and/or SW RF Kill no longer active, restarting " "device\n"); @@ -6469,10 +6578,10 @@ static void iwl_bg_rf_kill(struct work_struct *work) #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) -static void iwl_bg_scan_check(struct work_struct *data) +static void iwl3945_bg_scan_check(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, scan_check.work); + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, scan_check.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -6485,22 +6594,22 @@ static void iwl_bg_scan_check(struct work_struct *data) jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - iwl_send_scan_abort(priv); + iwl3945_send_scan_abort(priv); } mutex_unlock(&priv->mutex); } -static void iwl_bg_request_scan(struct work_struct *data) +static void iwl3945_bg_request_scan(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, request_scan); - struct iwl_host_cmd cmd = { + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, request_scan); + struct iwl3945_host_cmd cmd = { .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl_scan_cmd), + .len = sizeof(struct iwl3945_scan_cmd), .meta.flags = CMD_SIZE_HUGE, }; int rc = 0; - struct iwl_scan_cmd *scan; + struct iwl3945_scan_cmd *scan; struct ieee80211_conf *conf = NULL; u8 direct_mask; int phymode; @@ -6509,7 +6618,7 @@ static void iwl_bg_request_scan(struct work_struct *data) mutex_lock(&priv->mutex); - if (!iwl_is_ready(priv)) { + if (!iwl3945_is_ready(priv)) { IWL_WARNING("request scan called when driver not ready.\n"); goto done; } @@ -6538,7 +6647,7 @@ static void iwl_bg_request_scan(struct work_struct *data) goto done; } - if (iwl_is_rfkill(priv)) { + if (iwl3945_is_rfkill(priv)) { IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); goto done; } @@ -6554,7 +6663,7 @@ static void iwl_bg_request_scan(struct work_struct *data) } if (!priv->scan) { - priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + + priv->scan = kmalloc(sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan) { rc = -ENOMEM; @@ -6562,12 +6671,12 @@ static void iwl_bg_request_scan(struct work_struct *data) } } scan = priv->scan; - memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); + memset(scan, 0, sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE); scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl3945_is_associated(priv)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -6604,14 +6713,14 @@ static void iwl_bg_request_scan(struct work_struct *data) if (priv->one_direct_scan) { IWL_DEBUG_SCAN ("Kicking off one direct scan for '%s'\n", - iwl_escape_essid(priv->direct_ssid, + iwl3945_escape_essid(priv->direct_ssid, priv->direct_ssid_len)); scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->direct_ssid_len; memcpy(scan->direct_scan[0].ssid, priv->direct_ssid, priv->direct_ssid_len); direct_mask = 1; - } else if (!iwl_is_associated(priv) && priv->essid_len) { + } else if (!iwl3945_is_associated(priv) && priv->essid_len) { scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->essid_len; memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); @@ -6622,7 +6731,7 @@ static void iwl_bg_request_scan(struct work_struct *data) /* 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.len = cpu_to_le16( - iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, + iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; @@ -6658,23 +6767,23 @@ static void iwl_bg_request_scan(struct work_struct *data) if (direct_mask) IWL_DEBUG_SCAN ("Initiating direct scan for %s.\n", - iwl_escape_essid(priv->essid, priv->essid_len)); + iwl3945_escape_essid(priv->essid, priv->essid_len)); else IWL_DEBUG_SCAN("Initiating indirect scan.\n"); scan->channel_count = - iwl_get_channels_for_scan( + iwl3945_get_channels_for_scan( priv, phymode, 1, /* active */ direct_mask, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); cmd.len += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl_scan_channel); + scan->channel_count * sizeof(struct iwl3945_scan_channel); cmd.data = scan; scan->len = cpu_to_le16(cmd.len); set_bit(STATUS_SCAN_HW, &priv->status); - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl3945_send_cmd_sync(priv, &cmd); if (rc) goto done; @@ -6685,50 +6794,52 @@ static void iwl_bg_request_scan(struct work_struct *data) return; done: - /* inform mac80211 sacn aborted */ + /* inform mac80211 scan aborted */ queue_work(priv->workqueue, &priv->scan_completed); mutex_unlock(&priv->mutex); } -static void iwl_bg_up(struct work_struct *data) +static void iwl3945_bg_up(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, up); + struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, up); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - __iwl_up(priv); + __iwl3945_up(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_restart(struct work_struct *data) +static void iwl3945_bg_restart(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); + struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, restart); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - iwl_down(priv); + iwl3945_down(priv); queue_work(priv->workqueue, &priv->up); } -static void iwl_bg_rx_replenish(struct work_struct *data) +static void iwl3945_bg_rx_replenish(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, rx_replenish); + struct iwl3945_priv *priv = + container_of(data, struct iwl3945_priv, rx_replenish); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_rx_replenish(priv); + iwl3945_rx_replenish(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_post_associate(struct work_struct *data) +#define IWL_DELAY_NEXT_SCAN (HZ*2) + +static void iwl3945_bg_post_associate(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, + struct iwl3945_priv *priv = container_of(data, struct iwl3945_priv, post_associate.work); int rc = 0; @@ -6754,16 +6865,16 @@ static void iwl_bg_post_associate(struct work_struct *data) mutex_unlock(&priv->mutex); return; } - iwl_scan_cancel_timeout(priv, 200); + iwl3945_scan_cancel_timeout(priv, 200); conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd)); + iwl3945_setup_rxon_timing(priv); + rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING, sizeof(priv->rxon_timing), &priv->rxon_timing); if (rc) IWL_WARNING("REPLY_RXON_TIMING failed - " @@ -6792,75 +6903,81 @@ static void iwl_bg_post_associate(struct work_struct *data) } - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); switch (priv->iw_mode) { case IEEE80211_IF_TYPE_STA: - iwl_rate_scale_init(priv->hw, IWL_AP_ID); + iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); break; case IEEE80211_IF_TYPE_IBSS: /* clear out the station table */ - iwl_clear_stations_table(priv); + iwl3945_clear_stations_table(priv); - iwl_add_station(priv, BROADCAST_ADDR, 0, 0); - iwl_add_station(priv, priv->bssid, 0, 0); + iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); + iwl3945_add_station(priv, priv->bssid, 0, 0); iwl3945_sync_sta(priv, IWL_STA_ID, (priv->phymode == MODE_IEEE80211A)? IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, CMD_ASYNC); - iwl_rate_scale_init(priv->hw, IWL_STA_ID); - iwl_send_beacon_cmd(priv); + iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); + iwl3945_send_beacon_cmd(priv); break; default: IWL_ERROR("%s Should not be called in %d mode\n", - __FUNCTION__, priv->iw_mode); + __FUNCTION__, priv->iw_mode); break; } - iwl_sequence_reset(priv); + iwl3945_sequence_reset(priv); -#ifdef CONFIG_IWLWIFI_QOS - iwl_activate_qos(priv, 0); -#endif /* CONFIG_IWLWIFI_QOS */ +#ifdef CONFIG_IWL3945_QOS + iwl3945_activate_qos(priv, 0); +#endif /* CONFIG_IWL3945_QOS */ + /* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; mutex_unlock(&priv->mutex); } -static void iwl_bg_abort_scan(struct work_struct *work) +static void iwl3945_bg_abort_scan(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, - abort_scan); + struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv, abort_scan); - if (!iwl_is_ready(priv)) + if (!iwl3945_is_ready(priv)) return; mutex_lock(&priv->mutex); set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); + iwl3945_send_scan_abort(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_scan_completed(struct work_struct *work) +static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); + +static void iwl3945_bg_scan_completed(struct work_struct *work) { - struct iwl_priv *priv = - container_of(work, struct iwl_priv, scan_completed); + struct iwl3945_priv *priv = + container_of(work, struct iwl3945_priv, scan_completed); IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; + if (priv->cache_conf) + iwl3945_mac_config(priv->hw, priv->cache_conf); + ieee80211_scan_completed(priv->hw); /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ mutex_lock(&priv->mutex); - iwl_hw_reg_send_txpower(priv); + iwl3945_hw_reg_send_txpower(priv); mutex_unlock(&priv->mutex); } @@ -6870,9 +6987,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) * *****************************************************************************/ -static int iwl_mac_start(struct ieee80211_hw *hw) +static int iwl3945_mac_start(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -6881,7 +6998,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) priv->is_open = 1; - if (!iwl_is_rfkill(priv)) + if (!iwl3945_is_rfkill(priv)) ieee80211_start_queues(priv->hw); mutex_unlock(&priv->mutex); @@ -6889,9 +7006,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw) return 0; } -static void iwl_mac_stop(struct ieee80211_hw *hw) +static void iwl3945_mac_stop(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -6901,19 +7018,25 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) * RXON_FILTER_ASSOC_MSK BIT */ priv->is_open = 0; - iwl_scan_cancel_timeout(priv, 100); + if (!iwl3945_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211("leave - RF not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + iwl3945_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211("leave\n"); } -static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, +static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *ctl) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -6925,17 +7048,17 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ctl->tx_rate); - if (iwl_tx_skb(priv, skb, ctl)) + if (iwl3945_tx_skb(priv, skb, ctl)) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211("leave\n"); return 0; } -static int iwl_mac_add_interface(struct ieee80211_hw *hw, +static int iwl3945_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; unsigned long flags; DECLARE_MAC_BUF(mac); @@ -6958,7 +7081,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); } - iwl_set_mode(priv, conf->type); + iwl3945_set_mode(priv, conf->type); IWL_DEBUG_MAC80211("leave\n"); mutex_unlock(&priv->mutex); @@ -6967,97 +7090,114 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, } /** - * iwl_mac_config - mac80211 config callback + * iwl3945_mac_config - mac80211 config callback * * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to * be set inappropriately and the driver currently sets the hardware up to * use it whenever needed. */ -static int iwl_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) +static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) { - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; + struct iwl3945_priv *priv = hw->priv; + const struct iwl3945_channel_info *ch_info; unsigned long flags; + int ret = 0; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); - if (!iwl_is_ready(priv)) { + if (!iwl3945_is_ready(priv)) { IWL_DEBUG_MAC80211("leave - not ready\n"); - mutex_unlock(&priv->mutex); - return -EIO; + ret = -EIO; + goto out; } /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only - * what is exposed through include/ declrations */ - if (unlikely(!iwl_param_disable_hw_scan && + * what is exposed through include/ declarations */ + if (unlikely(!iwl3945_param_disable_hw_scan && test_bit(STATUS_SCANNING, &priv->status))) { - IWL_DEBUG_MAC80211("leave - scanning\n"); + + if (priv->cache_conf) + IWL_DEBUG_MAC80211("leave - still scanning\n"); + else { + /* Cache the configuration now so that we can + * replay it after the hardware scan is finished. */ + priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL); + if (priv->cache_conf) { + memcpy(priv->cache_conf, conf, sizeof(*conf)); + IWL_DEBUG_MAC80211("leave - scanning\n"); + } else { + IWL_DEBUG_MAC80211("leave - no memory\n"); + ret = -ENOMEM; + } + } mutex_unlock(&priv->mutex); - return 0; + return ret; } spin_lock_irqsave(&priv->lock, flags); - ch_info = iwl_get_channel_info(priv, conf->phymode, conf->channel); + ch_info = iwl3945_get_channel_info(priv, conf->phymode, conf->channel); if (!is_channel_valid(ch_info)) { IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", conf->channel, conf->phymode); IWL_DEBUG_MAC80211("leave - invalid channel\n"); spin_unlock_irqrestore(&priv->lock, flags); - mutex_unlock(&priv->mutex); - return -EINVAL; + ret = -EINVAL; + goto out; } - iwl_set_rxon_channel(priv, conf->phymode, conf->channel); + iwl3945_set_rxon_channel(priv, conf->phymode, conf->channel); - iwl_set_flags_for_phymode(priv, conf->phymode); + iwl3945_set_flags_for_phymode(priv, conf->phymode); /* The list of supported rates and rate mask can be different * for each phymode; since the phymode may have changed, reset * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); + iwl3945_set_rate(priv); spin_unlock_irqrestore(&priv->lock, flags); #ifdef IEEE80211_CONF_CHANNEL_SWITCH if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { - iwl_hw_channel_switch(priv, conf->channel); - mutex_unlock(&priv->mutex); - return 0; + iwl3945_hw_channel_switch(priv, conf->channel); + goto out; } #endif - iwl_radio_kill_sw(priv, !conf->radio_enabled); + iwl3945_radio_kill_sw(priv, !conf->radio_enabled); if (!conf->radio_enabled) { IWL_DEBUG_MAC80211("leave - radio disabled\n"); - mutex_unlock(&priv->mutex); - return 0; + goto out; } - if (iwl_is_rfkill(priv)) { + if (iwl3945_is_rfkill(priv)) { IWL_DEBUG_MAC80211("leave - RF kill\n"); - mutex_unlock(&priv->mutex); - return -EIO; + ret = -EIO; + goto out; } - iwl_set_rate(priv); + iwl3945_set_rate(priv); if (memcmp(&priv->active_rxon, &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); else IWL_DEBUG_INFO("No re-sending same RXON configuration.\n"); IWL_DEBUG_MAC80211("leave\n"); +out: + if (priv->cache_conf) { + kfree(priv->cache_conf); + priv->cache_conf = NULL; + } mutex_unlock(&priv->mutex); - - return 0; + return ret; } -static void iwl_config_ap(struct iwl_priv *priv) +static void iwl3945_config_ap(struct iwl3945_priv *priv) { int rc = 0; @@ -7069,12 +7209,12 @@ static void iwl_config_ap(struct iwl_priv *priv) /* RXON - unassoc (to set timing command) */ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); /* RXON Timing */ - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + memset(&priv->rxon_timing, 0, sizeof(struct iwl3945_rxon_time_cmd)); + iwl3945_setup_rxon_timing(priv); + rc = iwl3945_send_cmd_pdu(priv, REPLY_RXON_TIMING, sizeof(priv->rxon_timing), &priv->rxon_timing); if (rc) IWL_WARNING("REPLY_RXON_TIMING failed - " @@ -7104,20 +7244,20 @@ static void iwl_config_ap(struct iwl_priv *priv) } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); - iwl_add_station(priv, BROADCAST_ADDR, 0, 0); + iwl3945_commit_rxon(priv); + iwl3945_add_station(priv, iwl3945_broadcast_addr, 0, 0); } - iwl_send_beacon_cmd(priv); + iwl3945_send_beacon_cmd(priv); /* FIXME - we need to add code here to detect a totally new * configuration, reset the AP, unassoc, rxon timing, assoc, * clear sta table, add BCAST sta... */ } -static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, +static int iwl3945_mac_config_interface(struct ieee80211_hw *hw, int if_id, struct ieee80211_if_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; DECLARE_MAC_BUF(mac); unsigned long flags; int rc; @@ -7172,11 +7312,14 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, priv->ibss_beacon = conf->beacon; } + if (iwl3945_is_rfkill(priv)) + goto done; + if (conf->bssid && !is_zero_ether_addr(conf->bssid) && !is_multicast_ether_addr(conf->bssid)) { /* If there is currently a HW scan going on in the background * then we need to cancel it else the RXON below will fail. */ - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl3945_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress " "after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); @@ -7192,20 +7335,21 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, memcpy(priv->bssid, conf->bssid, ETH_ALEN); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) - iwl_config_ap(priv); + iwl3945_config_ap(priv); else { - rc = iwl_commit_rxon(priv); + rc = iwl3945_commit_rxon(priv); if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) - iwl_add_station(priv, + iwl3945_add_station(priv, priv->active_rxon.bssid_addr, 1, 0); } } else { - iwl_scan_cancel_timeout(priv, 100); + iwl3945_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); } + done: spin_lock_irqsave(&priv->lock, flags); if (!conf->ssid_len) memset(priv->essid, 0, IW_ESSID_MAX_SIZE); @@ -7221,32 +7365,33 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, return 0; } -static void iwl_configure_filter(struct ieee80211_hw *hw, +static void iwl3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, int mc_count, struct dev_addr_list *mc_list) { /* * XXX: dummy - * see also iwl_connection_init_rx_config + * see also iwl3945_connection_init_rx_config */ *total_flags = 0; } -static void iwl_mac_remove_interface(struct ieee80211_hw *hw, +static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - cancel_delayed_work(&priv->post_associate); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); - + if (iwl3945_is_ready_rf(priv)) { + iwl3945_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv); + } if (priv->interface_id == conf->if_id) { priv->interface_id = 0; memset(priv->bssid, 0, ETH_ALEN); @@ -7259,19 +7404,18 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, } -#define IWL_DELAY_NEXT_SCAN (HZ*2) -static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) +static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) { int rc = 0; unsigned long flags; - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); spin_lock_irqsave(&priv->lock, flags); - if (!iwl_is_ready_rf(priv)) { + if (!iwl3945_is_ready_rf(priv)) { rc = -EIO; IWL_DEBUG_MAC80211("leave - not ready or exit pending\n"); goto out_unlock; @@ -7283,17 +7427,21 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } + /* we don't schedule scan within next_scan_jiffies period */ + if (priv->next_scan_jiffies && + time_after(priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN; + goto out_unlock; + } /* if we just finished scan ask for delay */ - if (priv->last_scan_jiffies && - time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, - jiffies)) { + if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + + IWL_DELAY_NEXT_SCAN, jiffies)) { rc = -EAGAIN; goto out_unlock; } if (len) { - IWL_DEBUG_SCAN("direct scan for " - "%s [%d]\n ", - iwl_escape_essid(ssid, len), (int)len); + IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", + iwl3945_escape_essid(ssid, len), (int)len); priv->one_direct_scan = 1; priv->direct_ssid_len = (u8) @@ -7302,7 +7450,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) } else priv->one_direct_scan = 0; - rc = iwl_scan_initiate(priv); + rc = iwl3945_scan_initiate(priv); IWL_DEBUG_MAC80211("leave\n"); @@ -7313,17 +7461,17 @@ out_unlock: return rc; } -static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, +static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, const u8 *local_addr, const u8 *addr, struct ieee80211_key_conf *key) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; int rc = 0; u8 sta_id; IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_param_hwcrypto) { + if (!iwl3945_param_hwcrypto) { IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); return -EOPNOTSUPP; } @@ -7332,7 +7480,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, /* only support pairwise keys */ return -EOPNOTSUPP; - sta_id = iwl_hw_find_station(priv, addr); + sta_id = iwl3945_hw_find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { DECLARE_MAC_BUF(mac); @@ -7343,24 +7491,24 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); + iwl3945_scan_cancel_timeout(priv, 100); switch (cmd) { case SET_KEY: - rc = iwl_update_sta_key_info(priv, key, sta_id); + rc = iwl3945_update_sta_key_info(priv, key, sta_id); if (!rc) { - iwl_set_rxon_hwcrypto(priv, 1); - iwl_commit_rxon(priv); + iwl3945_set_rxon_hwcrypto(priv, 1); + iwl3945_commit_rxon(priv); key->hw_key_idx = sta_id; IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n"); key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; } break; case DISABLE_KEY: - rc = iwl_clear_sta_key_info(priv, sta_id); + rc = iwl3945_clear_sta_key_info(priv, sta_id); if (!rc) { - iwl_set_rxon_hwcrypto(priv, 0); - iwl_commit_rxon(priv); + iwl3945_set_rxon_hwcrypto(priv, 0); + iwl3945_commit_rxon(priv); IWL_DEBUG_MAC80211("disable hwcrypto key\n"); } break; @@ -7374,18 +7522,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return rc; } -static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, +static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, int queue, const struct ieee80211_tx_queue_params *params) { - struct iwl_priv *priv = hw->priv; -#ifdef CONFIG_IWLWIFI_QOS + struct iwl3945_priv *priv = hw->priv; +#ifdef CONFIG_IWL3945_QOS unsigned long flags; int q; -#endif /* CONFIG_IWL_QOS */ +#endif /* CONFIG_IWL3945_QOS */ IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl3945_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); return -EIO; } @@ -7395,7 +7543,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, return 0; } -#ifdef CONFIG_IWLWIFI_QOS +#ifdef CONFIG_IWL3945_QOS if (!priv->qos_data.qos_enable) { priv->qos_data.qos_active = 0; IWL_DEBUG_MAC80211("leave - qos not enabled\n"); @@ -7418,30 +7566,30 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, mutex_lock(&priv->mutex); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) - iwl_activate_qos(priv, 1); - else if (priv->assoc_id && iwl_is_associated(priv)) - iwl_activate_qos(priv, 0); + iwl3945_activate_qos(priv, 1); + else if (priv->assoc_id && iwl3945_is_associated(priv)) + iwl3945_activate_qos(priv, 0); mutex_unlock(&priv->mutex); -#endif /*CONFIG_IWLWIFI_QOS */ +#endif /*CONFIG_IWL3945_QOS */ IWL_DEBUG_MAC80211("leave\n"); return 0; } -static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, +static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw, struct ieee80211_tx_queue_stats *stats) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; int i, avail; - struct iwl_tx_queue *txq; - struct iwl_queue *q; + struct iwl3945_tx_queue *txq; + struct iwl3945_queue *q; unsigned long flags; IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl3945_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); return -EIO; } @@ -7451,7 +7599,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, for (i = 0; i < AC_NUM; i++) { txq = &priv->txq[i]; q = &txq->q; - avail = iwl_queue_space(q); + avail = iwl3945_queue_space(q); stats->data[i].len = q->n_window - avail; stats->data[i].limit = q->n_window - q->high_mark; @@ -7465,7 +7613,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, return 0; } -static int iwl_mac_get_stats(struct ieee80211_hw *hw, +static int iwl3945_mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { IWL_DEBUG_MAC80211("enter\n"); @@ -7474,7 +7622,7 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, return 0; } -static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw) +static u64 iwl3945_mac_get_tsf(struct ieee80211_hw *hw) { IWL_DEBUG_MAC80211("enter\n"); IWL_DEBUG_MAC80211("leave\n"); @@ -7482,16 +7630,16 @@ static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw) return 0; } -static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) +static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; unsigned long flags; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); -#ifdef CONFIG_IWLWIFI_QOS - iwl_reset_qos(priv); +#ifdef CONFIG_IWL3945_QOS + iwl3945_reset_qos(priv); #endif cancel_delayed_work(&priv->post_associate); @@ -7514,13 +7662,19 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->lock, flags); + if (!iwl3945_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211("leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + /* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { - iwl_scan_cancel_timeout(priv, 100); + iwl3945_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); } /* Per mac80211.h: This is only used in IBSS mode... */ @@ -7531,15 +7685,9 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) return; } - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211("leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - priv->only_active_channel = 0; - iwl_set_rate(priv); + iwl3945_set_rate(priv); mutex_unlock(&priv->mutex); @@ -7547,16 +7695,16 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, +static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { - struct iwl_priv *priv = hw->priv; + struct iwl3945_priv *priv = hw->priv; unsigned long flags; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl3945_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); mutex_unlock(&priv->mutex); return -EIO; @@ -7580,8 +7728,8 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, IWL_DEBUG_MAC80211("leave\n"); spin_unlock_irqrestore(&priv->lock, flags); -#ifdef CONFIG_IWLWIFI_QOS - iwl_reset_qos(priv); +#ifdef CONFIG_IWL3945_QOS + iwl3945_reset_qos(priv); #endif queue_work(priv->workqueue, &priv->post_associate.work); @@ -7597,7 +7745,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL3945_DEBUG /* * The following adds a new attribute to the sysfs representation @@ -7609,7 +7757,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, static ssize_t show_debug_level(struct device_driver *d, char *buf) { - return sprintf(buf, "0x%08X\n", iwl_debug_level); + return sprintf(buf, "0x%08X\n", iwl3945_debug_level); } static ssize_t store_debug_level(struct device_driver *d, const char *buf, size_t count) @@ -7622,7 +7770,7 @@ static ssize_t store_debug_level(struct device_driver *d, printk(KERN_INFO DRV_NAME ": %s is not in hex or decimal form.\n", buf); else - iwl_debug_level = val; + iwl3945_debug_level = val; return strnlen(buf, count); } @@ -7630,7 +7778,7 @@ static ssize_t store_debug_level(struct device_driver *d, static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, store_debug_level); -#endif /* CONFIG_IWLWIFI_DEBUG */ +#endif /* CONFIG_IWL3945_DEBUG */ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, char *buf) @@ -7641,7 +7789,7 @@ static ssize_t show_rf_kill(struct device *d, * 2 - HW based RF kill active * 3 - Both HW and SW based RF kill active */ - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); @@ -7652,10 +7800,10 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; mutex_lock(&priv->mutex); - iwl_radio_kill_sw(priv, buf[0] == '1'); + iwl3945_radio_kill_sw(priv, buf[0] == '1'); mutex_unlock(&priv->mutex); return count; @@ -7666,12 +7814,12 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); static ssize_t show_temperature(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; - if (!iwl_is_alive(priv)) + if (!iwl3945_is_alive(priv)) return -EAGAIN; - return sprintf(buf, "%d\n", iwl_hw_get_temperature(priv)); + return sprintf(buf, "%d\n", iwl3945_hw_get_temperature(priv)); } static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); @@ -7680,15 +7828,15 @@ static ssize_t show_rs_window(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = d->driver_data; - return iwl_fill_rs_info(priv->hw, buf, IWL_AP_ID); + struct iwl3945_priv *priv = d->driver_data; + return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID); } static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL); static ssize_t show_tx_power(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; return sprintf(buf, "%d\n", priv->user_txpower_limit); } @@ -7696,7 +7844,7 @@ static ssize_t store_tx_power(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; char *p = (char *)buf; u32 val; @@ -7705,7 +7853,7 @@ static ssize_t store_tx_power(struct device *d, printk(KERN_INFO DRV_NAME ": %s is not in decimal form.\n", buf); else - iwl_hw_reg_set_txpower(priv, val); + iwl3945_hw_reg_set_txpower(priv, val); return count; } @@ -7715,7 +7863,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); static ssize_t show_flags(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); } @@ -7724,19 +7872,19 @@ static ssize_t store_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; u32 flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.flags) != flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl3945_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", flags); priv->staging_rxon.flags = cpu_to_le32(flags); - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -7749,7 +7897,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); static ssize_t show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.filter_flags)); @@ -7759,20 +7907,20 @@ static ssize_t store_filter_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl3945_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.filter_flags = " "0x%04X\n", filter_flags); priv->staging_rxon.filter_flags = cpu_to_le32(filter_flags); - iwl_commit_rxon(priv); + iwl3945_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -7786,20 +7934,20 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, static ssize_t show_tune(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", (priv->phymode << 8) | le16_to_cpu(priv->active_rxon.channel)); } -static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode); +static void iwl3945_set_flags_for_phymode(struct iwl3945_priv *priv, u8 phymode); static ssize_t store_tune(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; char *p = (char *)buf; u16 tune = simple_strtoul(p, &p, 0); u8 phymode = (tune >> 8) & 0xff; @@ -7810,9 +7958,9 @@ static ssize_t store_tune(struct device *d, mutex_lock(&priv->mutex); if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || (priv->phymode != phymode)) { - const struct iwl_channel_info *ch_info; + const struct iwl3945_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, phymode, channel); + ch_info = iwl3945_get_channel_info(priv, phymode, channel); if (!ch_info) { IWL_WARNING("Requested invalid phymode/channel " "combination: %d %d\n", phymode, channel); @@ -7821,18 +7969,18 @@ static ssize_t store_tune(struct device *d, } /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl3945_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing phymode and " "rxon.channel = %d %d\n", phymode, channel); - iwl_set_rxon_channel(priv, phymode, channel); - iwl_set_flags_for_phymode(priv, phymode); + iwl3945_set_rxon_channel(priv, phymode, channel); + iwl3945_set_flags_for_phymode(priv, phymode); - iwl_set_rate(priv); - iwl_commit_rxon(priv); + iwl3945_set_rate(priv); + iwl3945_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -7842,13 +7990,13 @@ static ssize_t store_tune(struct device *d, static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT static ssize_t show_measurement(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_spectrum_notification measure_report; + struct iwl3945_priv *priv = dev_get_drvdata(d); + struct iwl3945_spectrum_notification measure_report; u32 size = sizeof(measure_report), len = 0, ofs = 0; u8 *data = (u8 *) & measure_report; unsigned long flags; @@ -7880,7 +8028,7 @@ static ssize_t store_measurement(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); struct ieee80211_measurement_params params = { .channel = le16_to_cpu(priv->active_rxon.channel), .start_time = cpu_to_le64(priv->last_tsf), @@ -7906,19 +8054,19 @@ static ssize_t store_measurement(struct device *d, IWL_DEBUG_INFO("Invoking measurement of type %d on " "channel %d (for '%s')\n", type, params.channel, buf); - iwl_get_measurement(priv, ¶ms, type); + iwl3945_get_measurement(priv, ¶ms, type); return count; } static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, show_measurement, store_measurement); -#endif /* CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT */ +#endif /* CONFIG_IWL3945_SPECTRUM_MEASUREMENT */ static ssize_t show_rate(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); unsigned long flags; int i; @@ -7929,13 +8077,13 @@ static ssize_t show_rate(struct device *d, i = priv->stations[IWL_STA_ID].current_rate.s.rate; spin_unlock_irqrestore(&priv->sta_lock, flags); - i = iwl_rate_index_from_plcp(i); + i = iwl3945_rate_index_from_plcp(i); if (i == -1) return sprintf(buf, "0\n"); return sprintf(buf, "%d%s\n", - (iwl_rates[i].ieee >> 1), - (iwl_rates[i].ieee & 0x1) ? ".5" : ""); + (iwl3945_rates[i].ieee >> 1), + (iwl3945_rates[i].ieee & 0x1) ? ".5" : ""); } static DEVICE_ATTR(rate, S_IRUSR, show_rate, NULL); @@ -7944,7 +8092,7 @@ static ssize_t store_retry_rate(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); priv->retry_rate = simple_strtoul(buf, NULL, 0); if (priv->retry_rate <= 0) @@ -7956,7 +8104,7 @@ static ssize_t store_retry_rate(struct device *d, static ssize_t show_retry_rate(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d", priv->retry_rate); } @@ -7967,14 +8115,14 @@ static ssize_t store_power_level(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); int rc; int mode; mode = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); - if (!iwl_is_ready(priv)) { + if (!iwl3945_is_ready(priv)) { rc = -EAGAIN; goto out; } @@ -7985,7 +8133,7 @@ static ssize_t store_power_level(struct device *d, mode |= IWL_POWER_ENABLED; if (mode != priv->power_mode) { - rc = iwl_send_power_mode(priv, IWL_POWER_LEVEL(mode)); + rc = iwl3945_send_power_mode(priv, IWL_POWER_LEVEL(mode)); if (rc) { IWL_DEBUG_MAC80211("failed setting power mode.\n"); goto out; @@ -8021,7 +8169,7 @@ static const s32 period_duration[] = { static ssize_t show_power_level(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); int level = IWL_POWER_LEVEL(priv->power_mode); char *p = buf; @@ -8056,18 +8204,18 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, static ssize_t show_channels(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); int len = 0, i; struct ieee80211_channel *channels = NULL; const struct ieee80211_hw_mode *hw_mode = NULL; int count = 0; - if (!iwl_is_ready(priv)) + if (!iwl3945_is_ready(priv)) return -EAGAIN; - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211G); + hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211G); if (!hw_mode) - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211B); + hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211B); if (hw_mode) { channels = hw_mode->channels; count = hw_mode->num_channels; @@ -8094,7 +8242,7 @@ static ssize_t show_channels(struct device *d, flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? "active/passive" : "passive only"); - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211A); + hw_mode = iwl3945_get_hw_mode(priv, MODE_IEEE80211A); if (hw_mode) { channels = hw_mode->channels; count = hw_mode->num_channels; @@ -8130,17 +8278,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); static ssize_t show_statistics(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); - u32 size = sizeof(struct iwl_notif_statistics); + struct iwl3945_priv *priv = dev_get_drvdata(d); + u32 size = sizeof(struct iwl3945_notif_statistics); u32 len = 0, ofs = 0; u8 *data = (u8 *) & priv->statistics; int rc = 0; - if (!iwl_is_alive(priv)) + if (!iwl3945_is_alive(priv)) return -EAGAIN; mutex_lock(&priv->mutex); - rc = iwl_send_statistics_request(priv); + rc = iwl3945_send_statistics_request(priv); mutex_unlock(&priv->mutex); if (rc) { @@ -8168,9 +8316,9 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); static ssize_t show_antenna(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); - if (!iwl_is_alive(priv)) + if (!iwl3945_is_alive(priv)) return -EAGAIN; return sprintf(buf, "%d\n", priv->antenna); @@ -8181,7 +8329,7 @@ static ssize_t store_antenna(struct device *d, const char *buf, size_t count) { int ant; - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl3945_priv *priv = dev_get_drvdata(d); if (count == 0) return 0; @@ -8193,7 +8341,7 @@ static ssize_t store_antenna(struct device *d, if ((ant >= 0) && (ant <= 2)) { IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant); - priv->antenna = (enum iwl_antenna)ant; + priv->antenna = (enum iwl3945_antenna)ant; } else IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant); @@ -8206,8 +8354,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); static ssize_t show_status(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; - if (!iwl_is_alive(priv)) + struct iwl3945_priv *priv = (struct iwl3945_priv *)d->driver_data; + if (!iwl3945_is_alive(priv)) return -EAGAIN; return sprintf(buf, "0x%08x\n", (int)priv->status); } @@ -8221,7 +8369,7 @@ static ssize_t dump_error_log(struct device *d, char *p = (char *)buf; if (p[0] == '1') - iwl_dump_nic_error_log((struct iwl_priv *)d->driver_data); + iwl3945_dump_nic_error_log((struct iwl3945_priv *)d->driver_data); return strnlen(buf, count); } @@ -8235,7 +8383,7 @@ static ssize_t dump_event_log(struct device *d, char *p = (char *)buf; if (p[0] == '1') - iwl_dump_nic_event_log((struct iwl_priv *)d->driver_data); + iwl3945_dump_nic_event_log((struct iwl3945_priv *)d->driver_data); return strnlen(buf, count); } @@ -8248,34 +8396,34 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); * *****************************************************************************/ -static void iwl_setup_deferred_work(struct iwl_priv *priv) +static void iwl3945_setup_deferred_work(struct iwl3945_priv *priv) { priv->workqueue = create_workqueue(DRV_NAME); init_waitqueue_head(&priv->wait_command_queue); - INIT_WORK(&priv->up, iwl_bg_up); - INIT_WORK(&priv->restart, iwl_bg_restart); - INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); - INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); - INIT_WORK(&priv->request_scan, iwl_bg_request_scan); - INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); - INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); - INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); - INIT_DELAYED_WORK(&priv->post_associate, iwl_bg_post_associate); - INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); - INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); - INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); - - iwl_hw_setup_deferred_work(priv); + INIT_WORK(&priv->up, iwl3945_bg_up); + INIT_WORK(&priv->restart, iwl3945_bg_restart); + INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); + INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed); + INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan); + INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan); + INIT_WORK(&priv->rf_kill, iwl3945_bg_rf_kill); + INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); + INIT_DELAYED_WORK(&priv->post_associate, iwl3945_bg_post_associate); + 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->scan_check, iwl3945_bg_scan_check); + + iwl3945_hw_setup_deferred_work(priv); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)priv); + iwl3945_irq_tasklet, (unsigned long)priv); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv) +static void iwl3945_cancel_deferred_work(struct iwl3945_priv *priv) { - iwl_hw_cancel_deferred_work(priv); + iwl3945_hw_cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); cancel_delayed_work(&priv->scan_check); @@ -8284,14 +8432,14 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->beacon_update); } -static struct attribute *iwl_sysfs_entries[] = { +static struct attribute *iwl3945_sysfs_entries[] = { &dev_attr_antenna.attr, &dev_attr_channels.attr, &dev_attr_dump_errors.attr, &dev_attr_dump_events.attr, &dev_attr_flags.attr, &dev_attr_filter_flags.attr, -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL3945_SPECTRUM_MEASUREMENT &dev_attr_measurement.attr, #endif &dev_attr_power_level.attr, @@ -8308,45 +8456,47 @@ static struct attribute *iwl_sysfs_entries[] = { NULL }; -static struct attribute_group iwl_attribute_group = { +static struct attribute_group iwl3945_attribute_group = { .name = NULL, /* put in device directory */ - .attrs = iwl_sysfs_entries, + .attrs = iwl3945_sysfs_entries, }; -static struct ieee80211_ops iwl_hw_ops = { - .tx = iwl_mac_tx, - .start = iwl_mac_start, - .stop = iwl_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .config = iwl_mac_config, - .config_interface = iwl_mac_config_interface, - .configure_filter = iwl_configure_filter, - .set_key = iwl_mac_set_key, - .get_stats = iwl_mac_get_stats, - .get_tx_stats = iwl_mac_get_tx_stats, - .conf_tx = iwl_mac_conf_tx, - .get_tsf = iwl_mac_get_tsf, - .reset_tsf = iwl_mac_reset_tsf, - .beacon_update = iwl_mac_beacon_update, - .hw_scan = iwl_mac_hw_scan +static struct ieee80211_ops iwl3945_hw_ops = { + .tx = iwl3945_mac_tx, + .start = iwl3945_mac_start, + .stop = iwl3945_mac_stop, + .add_interface = iwl3945_mac_add_interface, + .remove_interface = iwl3945_mac_remove_interface, + .config = iwl3945_mac_config, + .config_interface = iwl3945_mac_config_interface, + .configure_filter = iwl3945_configure_filter, + .set_key = iwl3945_mac_set_key, + .get_stats = iwl3945_mac_get_stats, + .get_tx_stats = iwl3945_mac_get_tx_stats, + .conf_tx = iwl3945_mac_conf_tx, + .get_tsf = iwl3945_mac_get_tsf, + .reset_tsf = iwl3945_mac_reset_tsf, + .beacon_update = iwl3945_mac_beacon_update, + .hw_scan = iwl3945_mac_hw_scan }; -static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; u32 pci_id; - struct iwl_priv *priv; + struct iwl3945_priv *priv; struct ieee80211_hw *hw; int i; - if (iwl_param_disable_hw_scan) { + /* Disabling hardware scan means that mac80211 will perform scans + * "the hard way", rather than using device's scan. */ + if (iwl3945_param_disable_hw_scan) { IWL_DEBUG_INFO("Disabling hw_scan\n"); - iwl_hw_ops.hw_scan = NULL; + iwl3945_hw_ops.hw_scan = NULL; } - if ((iwl_param_queues_num > IWL_MAX_NUM_QUEUES) || - (iwl_param_queues_num < IWL_MIN_NUM_QUEUES)) { + if ((iwl3945_param_queues_num > IWL_MAX_NUM_QUEUES) || + (iwl3945_param_queues_num < IWL_MIN_NUM_QUEUES)) { IWL_ERROR("invalid queues_num, should be between %d and %d\n", IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES); err = -EINVAL; @@ -8355,7 +8505,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* mac80211 allocates memory for this device instance, including * space for this driver's private structure */ - hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwl_hw_ops); + hw = ieee80211_alloc_hw(sizeof(struct iwl3945_priv), &iwl3945_hw_ops); if (hw == NULL) { IWL_ERROR("Can not allocate network device\n"); err = -ENOMEM; @@ -8370,9 +8520,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->hw = hw; priv->pci_dev = pdev; - priv->antenna = (enum iwl_antenna)iwl_param_antenna; -#ifdef CONFIG_IWLWIFI_DEBUG - iwl_debug_level = iwl_param_debug; + + /* Select antenna (may be helpful if only one antenna is connected) */ + priv->antenna = (enum iwl3945_antenna)iwl3945_param_antenna; +#ifdef CONFIG_IWL3945_DEBUG + iwl3945_debug_level = iwl3945_param_debug; atomic_set(&priv->restrict_refcnt, 0); #endif priv->retry_rate = 1; @@ -8391,6 +8543,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Tell mac80211 our Tx characteristics */ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; + /* 4 EDCA QOS priorities */ hw->queues = 4; spin_lock_init(&priv->lock); @@ -8411,7 +8564,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - iwl_clear_stations_table(priv); + /* Clear the driver's (not device's) station table */ + iwl3945_clear_stations_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; @@ -8430,9 +8584,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_request_regions(pdev, DRV_NAME); if (err) goto out_pci_disable_device; + /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, 0x41, 0x00); + priv->hw_base = pci_iomap(pdev, 0, 0); if (!priv->hw_base) { err = -ENODEV; @@ -8445,7 +8601,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Initialize module parameter values here */ - if (iwl_param_disable) { + /* Disable radio (SW RF KILL) via parameter when loading driver */ + if (iwl3945_param_disable) { set_bit(STATUS_RF_KILL_SW, &priv->status); IWL_DEBUG_INFO("Radio disabled.\n"); } @@ -8480,34 +8637,36 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->is_abg ? "A" : ""); /* Device-specific setup */ - if (iwl_hw_set_hw_setting(priv)) { + if (iwl3945_hw_set_hw_setting(priv)) { IWL_ERROR("failed to set hw settings\n"); mutex_unlock(&priv->mutex); goto out_iounmap; } -#ifdef CONFIG_IWLWIFI_QOS - if (iwl_param_qos_enable) +#ifdef CONFIG_IWL3945_QOS + if (iwl3945_param_qos_enable) priv->qos_data.qos_enable = 1; - iwl_reset_qos(priv); + iwl3945_reset_qos(priv); priv->qos_data.qos_active = 0; priv->qos_data.qos_cap.val = 0; -#endif /* CONFIG_IWLWIFI_QOS */ +#endif /* CONFIG_IWL3945_QOS */ - iwl_set_rxon_channel(priv, MODE_IEEE80211G, 6); - iwl_setup_deferred_work(priv); - iwl_setup_rx_handlers(priv); + iwl3945_set_rxon_channel(priv, MODE_IEEE80211G, 6); + iwl3945_setup_deferred_work(priv); + iwl3945_setup_rx_handlers(priv); priv->rates_mask = IWL_RATES_MASK; /* If power management is turned on, default to AC mode */ priv->power_mode = IWL_POWER_AC; priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; + iwl3945_disable_interrupts(priv); + pci_enable_msi(pdev); - err = request_irq(pdev->irq, iwl_isr, IRQF_SHARED, DRV_NAME, priv); + err = request_irq(pdev->irq, iwl3945_isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERROR("Error allocating IRQ %d\n", pdev->irq); goto out_disable_msi; @@ -8515,7 +8674,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mutex_lock(&priv->mutex); - err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); + err = sysfs_create_group(&pdev->dev.kobj, &iwl3945_attribute_group); if (err) { IWL_ERROR("failed to create sysfs device attributes\n"); mutex_unlock(&priv->mutex); @@ -8524,7 +8683,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* fetch ucode file from disk, alloc and copy to bus-master buffers ... * ucode filename and max sizes are card-specific. */ - err = iwl_read_ucode(priv); + err = iwl3945_read_ucode(priv); if (err) { IWL_ERROR("Could not read microcode: %d\n", err); mutex_unlock(&priv->mutex); @@ -8533,16 +8692,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mutex_unlock(&priv->mutex); - IWL_DEBUG_INFO("Queing UP work.\n"); + IWL_DEBUG_INFO("Queueing UP work.\n"); queue_work(priv->workqueue, &priv->up); return 0; out_pci_alloc: - iwl_dealloc_ucode_pci(priv); + iwl3945_dealloc_ucode_pci(priv); - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); out_release_irq: free_irq(pdev->irq, priv); @@ -8551,7 +8710,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_disable_msi(pdev); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - iwl_unset_hw_setting(priv); + iwl3945_unset_hw_setting(priv); out_iounmap: pci_iounmap(pdev, priv->hw_base); @@ -8566,9 +8725,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } -static void iwl_pci_remove(struct pci_dev *pdev) +static void iwl3945_pci_remove(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl3945_priv *priv = pci_get_drvdata(pdev); struct list_head *p, *q; int i; @@ -8579,37 +8738,37 @@ static void iwl_pci_remove(struct pci_dev *pdev) mutex_lock(&priv->mutex); set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); + __iwl3945_down(priv); mutex_unlock(&priv->mutex); /* Free MAC hash list for ADHOC */ for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { list_del(p); - kfree(list_entry(p, struct iwl_ibss_seq, list)); + kfree(list_entry(p, struct iwl3945_ibss_seq, list)); } } - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); - iwl_dealloc_ucode_pci(priv); + iwl3945_dealloc_ucode_pci(priv); if (priv->rxq.bd) - iwl_rx_queue_free(priv, &priv->rxq); - iwl_hw_txq_ctx_free(priv); + iwl3945_rx_queue_free(priv, &priv->rxq); + iwl3945_hw_txq_ctx_free(priv); - iwl_unset_hw_setting(priv); - iwl_clear_stations_table(priv); + iwl3945_unset_hw_setting(priv); + iwl3945_clear_stations_table(priv); if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); - iwl_rate_control_unregister(priv->hw); + iwl3945_rate_control_unregister(priv->hw); } /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); - /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes + /* ieee80211_unregister_hw calls iwl3945_mac_stop, which flushes * priv->workqueue... so we can't take down the workqueue * until now... */ destroy_workqueue(priv->workqueue); @@ -8635,16 +8794,16 @@ static void iwl_pci_remove(struct pci_dev *pdev) #ifdef CONFIG_PM -static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl3945_priv *priv = pci_get_drvdata(pdev); mutex_lock(&priv->mutex); set_bit(STATUS_IN_SUSPEND, &priv->status); /* Take down the device; powers it off, etc. */ - __iwl_down(priv); + __iwl3945_down(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); @@ -8658,7 +8817,7 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -static void iwl_resume(struct iwl_priv *priv) +static void iwl3945_resume(struct iwl3945_priv *priv) { unsigned long flags; @@ -8667,47 +8826,47 @@ static void iwl_resume(struct iwl_priv *priv) * Without all of the following, resume will not attempt to take * down the NIC (it shouldn't really need to) and will just try * and bring the NIC back up. However that fails during the - * ucode verification process. This then causes iwl_down to be - * called *after* iwl_hw_nic_init() has succeeded -- which + * ucode verification process. This then causes iwl3945_down to be + * called *after* iwl3945_hw_nic_init() has succeeded -- which * then lets the next init sequence succeed. So, we've * replicated all of that NIC init code here... */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_hw_nic_init(priv); + iwl3945_hw_nic_init(priv); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl3945_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl3945_disable_interrupts(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + iwl3945_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG, + if (!iwl3945_grab_nic_access(priv)) { + iwl3945_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - iwl_release_restricted_access(priv); + iwl3945_release_nic_access(priv); } spin_unlock_irqrestore(&priv->lock, flags); udelay(5); - iwl_hw_nic_reset(priv); + iwl3945_hw_nic_reset(priv); /* Bring the device back up */ clear_bit(STATUS_IN_SUSPEND, &priv->status); queue_work(priv->workqueue, &priv->up); } -static int iwl_pci_resume(struct pci_dev *pdev) +static int iwl3945_pci_resume(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl3945_priv *priv = pci_get_drvdata(pdev); int err; printk(KERN_INFO "Coming out of suspend...\n"); @@ -8726,7 +8885,7 @@ static int iwl_pci_resume(struct pci_dev *pdev) */ pci_write_config_byte(pdev, 0x41, 0x00); - iwl_resume(priv); + iwl3945_resume(priv); mutex_unlock(&priv->mutex); return 0; @@ -8740,33 +8899,33 @@ static int iwl_pci_resume(struct pci_dev *pdev) * *****************************************************************************/ -static struct pci_driver iwl_driver = { +static struct pci_driver iwl3945_driver = { .name = DRV_NAME, - .id_table = iwl_hw_card_ids, - .probe = iwl_pci_probe, - .remove = __devexit_p(iwl_pci_remove), + .id_table = iwl3945_hw_card_ids, + .probe = iwl3945_pci_probe, + .remove = __devexit_p(iwl3945_pci_remove), #ifdef CONFIG_PM - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, + .suspend = iwl3945_pci_suspend, + .resume = iwl3945_pci_resume, #endif }; -static int __init iwl_init(void) +static int __init iwl3945_init(void) { int ret; printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); - ret = pci_register_driver(&iwl_driver); + ret = pci_register_driver(&iwl3945_driver); if (ret) { IWL_ERROR("Unable to initialize PCI module\n"); return ret; } -#ifdef CONFIG_IWLWIFI_DEBUG - ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); +#ifdef CONFIG_IWL3945_DEBUG + ret = driver_create_file(&iwl3945_driver.driver, &driver_attr_debug_level); if (ret) { IWL_ERROR("Unable to create driver sysfs file\n"); - pci_unregister_driver(&iwl_driver); + pci_unregister_driver(&iwl3945_driver); return ret; } #endif @@ -8774,32 +8933,32 @@ static int __init iwl_init(void) return ret; } -static void __exit iwl_exit(void) +static void __exit iwl3945_exit(void) { -#ifdef CONFIG_IWLWIFI_DEBUG - driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); +#ifdef CONFIG_IWL3945_DEBUG + driver_remove_file(&iwl3945_driver.driver, &driver_attr_debug_level); #endif - pci_unregister_driver(&iwl_driver); + pci_unregister_driver(&iwl3945_driver); } -module_param_named(antenna, iwl_param_antenna, int, 0444); +module_param_named(antenna, iwl3945_param_antenna, int, 0444); MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(disable, iwl_param_disable, int, 0444); +module_param_named(disable, iwl3945_param_disable, int, 0444); MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); -module_param_named(hwcrypto, iwl_param_hwcrypto, int, 0444); +module_param_named(hwcrypto, iwl3945_param_hwcrypto, int, 0444); MODULE_PARM_DESC(hwcrypto, "using hardware crypto engine (default 0 [software])\n"); -module_param_named(debug, iwl_param_debug, int, 0444); +module_param_named(debug, iwl3945_param_debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); -module_param_named(disable_hw_scan, iwl_param_disable_hw_scan, int, 0444); +module_param_named(disable_hw_scan, iwl3945_param_disable_hw_scan, int, 0444); MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); -module_param_named(queues_num, iwl_param_queues_num, int, 0444); +module_param_named(queues_num, iwl3945_param_queues_num, int, 0444); MODULE_PARM_DESC(queues_num, "number of hw queues."); /* QoS */ -module_param_named(qos_enable, iwl_param_qos_enable, int, 0444); +module_param_named(qos_enable, iwl3945_param_qos_enable, int, 0444); MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); -module_exit(iwl_exit); -module_init(iwl_init); +module_exit(iwl3945_exit); +module_init(iwl3945_init); diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 8f85564..ba85205 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -27,16 +27,6 @@ * *****************************************************************************/ -/* - * NOTE: This file (iwl-base.c) is used to build to multiple hardware targets - * by defining IWL to either 3945 or 4965. The Makefile used when building - * the base targets will create base-3945.o and base-4965.o - * - * The eventual goal is to move as many of the #if IWL / #endif blocks out of - * this file and into the hardware specific implementation files (iwl-XXXX.c) - * and leave only the common (non #ifdef sprinkled) code in this file - */ - #include #include #include @@ -56,16 +46,16 @@ #include -#define IWL 4965 - -#include "iwlwifi.h" #include "iwl-4965.h" #include "iwl-helpers.h" -#ifdef CONFIG_IWLWIFI_DEBUG -u32 iwl_debug_level; +#ifdef CONFIG_IWL4965_DEBUG +u32 iwl4965_debug_level; #endif +static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq); + /****************************************************************************** * * module boiler plate @@ -73,13 +63,14 @@ u32 iwl_debug_level; ******************************************************************************/ /* module parameters */ -int iwl_param_disable_hw_scan; -int iwl_param_debug; -int iwl_param_disable; /* def: enable radio */ -int iwl_param_antenna; /* def: 0 = both antennas (use diversity) */ -int iwl_param_hwcrypto; /* def: using software encryption */ -int iwl_param_qos_enable = 1; -int iwl_param_queues_num = IWL_MAX_NUM_QUEUES; +static int iwl4965_param_disable_hw_scan; /* def: 0 = use 4965's h/w scan */ +static int iwl4965_param_debug; /* def: 0 = minimal debug log messages */ +static int iwl4965_param_disable; /* def: enable radio */ +static int iwl4965_param_antenna; /* def: 0 = both antennas (use diversity) */ +int iwl4965_param_hwcrypto; /* def: using software encryption */ +static int iwl4965_param_qos_enable = 1; /* def: 1 = use quality of service */ +int iwl4965_param_queues_num = IWL_MAX_NUM_QUEUES; /* def: 16 Tx queues */ +int iwl4965_param_amsdu_size_8K; /* def: enable 8K amsdu size */ /* * module name, copyright, version, etc. @@ -88,19 +79,19 @@ int iwl_param_queues_num = IWL_MAX_NUM_QUEUES; #define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link 4965AGN driver for Linux" -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG #define VD "d" #else #define VD #endif -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #define VS "s" #else #define VS #endif -#define IWLWIFI_VERSION "1.1.17k" VD VS +#define IWLWIFI_VERSION "1.2.22k" VD VS #define DRV_COPYRIGHT "Copyright(c) 2003-2007 Intel Corporation" #define DRV_VERSION IWLWIFI_VERSION @@ -125,8 +116,8 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) return NULL; } -static const struct ieee80211_hw_mode *iwl_get_hw_mode( - struct iwl_priv *priv, int mode) +static const struct ieee80211_hw_mode *iwl4965_get_hw_mode( + struct iwl4965_priv *priv, int mode) { int i; @@ -137,7 +128,7 @@ static const struct ieee80211_hw_mode *iwl_get_hw_mode( return NULL; } -static int iwl_is_empty_essid(const char *essid, int essid_len) +static int iwl4965_is_empty_essid(const char *essid, int essid_len) { /* Single white space is for Linksys APs */ if (essid_len == 1 && essid[0] == ' ') @@ -153,13 +144,13 @@ static int iwl_is_empty_essid(const char *essid, int essid_len) return 1; } -static const char *iwl_escape_essid(const char *essid, u8 essid_len) +static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) { static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; const char *s = essid; char *d = escaped; - if (iwl_is_empty_essid(essid, essid_len)) { + if (iwl4965_is_empty_essid(essid, essid_len)) { memcpy(escaped, "", sizeof("")); return escaped; } @@ -177,10 +168,10 @@ static const char *iwl_escape_essid(const char *essid, u8 essid_len) return escaped; } -static void iwl_print_hex_dump(int level, void *p, u32 len) +static void iwl4965_print_hex_dump(int level, void *p, u32 len) { -#ifdef CONFIG_IWLWIFI_DEBUG - if (!(iwl_debug_level & level)) +#ifdef CONFIG_IWL4965_DEBUG + if (!(iwl4965_debug_level & level)) return; print_hex_dump(KERN_DEBUG, "iwl data: ", DUMP_PREFIX_OFFSET, 16, 1, @@ -193,24 +184,33 @@ static void iwl_print_hex_dump(int level, void *p, u32 len) * * Theory of operation * - * A queue is a circular buffers with 'Read' and 'Write' pointers. - * 2 empty entries always kept in the buffer to protect from overflow. + * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer + * of buffer descriptors, each of which points to one or more data buffers for + * the device to read from or fill. Driver and device exchange status of each + * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty + * entries in each circular buffer, to protect against confusing empty and full + * queue states. + * + * The device reads or writes the data in the queues via the device's several + * DMA/FIFO channels. Each queue is mapped to a single DMA channel. * * For Tx queue, there are low mark and high mark limits. If, after queuing * the packet for Tx, free space become < low mark, Tx queue stopped. When * reclaiming packets (on 'tx done IRQ), if free space become > high mark, * Tx queue resumed. * - * The IWL operates with six queues, one receive queue in the device's - * sram, one transmit queue for sending commands to the device firmware, - * and four transmit queues for data. + * The 4965 operates with up to 17 queues: One receive queue, one transmit + * queue (#4) for sending commands to the device firmware, and 15 other + * Tx queues that may be mapped to prioritized Tx DMA/FIFO channels. + * + * See more detailed info in iwl-4965-hw.h. ***************************************************/ -static int iwl_queue_space(const struct iwl_queue *q) +static int iwl4965_queue_space(const struct iwl4965_queue *q) { - int s = q->last_used - q->first_empty; + int s = q->read_ptr - q->write_ptr; - if (q->last_used > q->first_empty) + if (q->read_ptr > q->write_ptr) s -= q->n_bd; if (s <= 0) @@ -222,42 +222,55 @@ static int iwl_queue_space(const struct iwl_queue *q) return s; } -/* XXX: n_bd must be power-of-two size */ -static inline int iwl_queue_inc_wrap(int index, int n_bd) +/** + * iwl4965_queue_inc_wrap - increment queue index, wrap back to beginning + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl4965_queue_inc_wrap(int index, int n_bd) { return ++index & (n_bd - 1); } -/* XXX: n_bd must be power-of-two size */ -static inline int iwl_queue_dec_wrap(int index, int n_bd) +/** + * iwl4965_queue_dec_wrap - decrement queue index, wrap back to end + * @index -- current index + * @n_bd -- total number of entries in queue (must be power of 2) + */ +static inline int iwl4965_queue_dec_wrap(int index, int n_bd) { return --index & (n_bd - 1); } -static inline int x2_queue_used(const struct iwl_queue *q, int i) +static inline int x2_queue_used(const struct iwl4965_queue *q, int i) { - return q->first_empty > q->last_used ? - (i >= q->last_used && i < q->first_empty) : - !(i < q->last_used && i >= q->first_empty); + return q->write_ptr > q->read_ptr ? + (i >= q->read_ptr && i < q->write_ptr) : + !(i < q->read_ptr && i >= q->write_ptr); } -static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) +static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) { + /* This is for scan command, the big buffer at end of command array */ if (is_huge) - return q->n_window; + return q->n_window; /* must be power of 2 */ + /* Otherwise, use normal size buffers */ return index & (q->n_window - 1); } -static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, +/** + * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes + */ +static int iwl4965_queue_init(struct iwl4965_priv *priv, struct iwl4965_queue *q, int count, int slots_num, u32 id) { q->n_bd = count; q->n_window = slots_num; q->id = id; - /* count must be power-of-two size, otherwise iwl_queue_inc_wrap - * and iwl_queue_dec_wrap are broken. */ + /* count must be power-of-two size, otherwise iwl4965_queue_inc_wrap + * and iwl4965_queue_dec_wrap are broken. */ BUG_ON(!is_power_of_2(count)); /* slots_num must be power-of-two size, otherwise @@ -272,27 +285,34 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q, if (q->high_mark < 2) q->high_mark = 2; - q->first_empty = q->last_used = 0; + q->write_ptr = q->read_ptr = 0; return 0; } -static int iwl_tx_queue_alloc(struct iwl_priv *priv, - struct iwl_tx_queue *txq, u32 id) +/** + * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue + */ +static int iwl4965_tx_queue_alloc(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, u32 id) { struct pci_dev *dev = priv->pci_dev; + /* Driver private data, only for Tx (not command) queues, + * not shared with device. */ if (id != IWL_CMD_QUEUE_NUM) { txq->txb = kmalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, GFP_KERNEL); if (!txq->txb) { - IWL_ERROR("kmalloc for auxilary BD " + IWL_ERROR("kmalloc for auxiliary BD " "structures failed\n"); goto error; } } else txq->txb = NULL; + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ txq->bd = pci_alloc_consistent(dev, sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, &txq->q.dma_addr); @@ -315,24 +335,33 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, return -ENOMEM; } -int iwl_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq, int slots_num, u32 txq_id) +/** + * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue + */ +int iwl4965_tx_queue_init(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) { struct pci_dev *dev = priv->pci_dev; int len; int rc = 0; - /* alocate command space + one big command for scan since scan - * command is very huge the system will not have two scan at the - * same time */ - len = sizeof(struct iwl_cmd) * slots_num; + /* + * Alloc buffer array for commands (Tx or other types of commands). + * For the command queue (#4), 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 data Tx queues (all other queues), no super-size command + * space is needed. + */ + len = sizeof(struct iwl4965_cmd) * slots_num; if (txq_id == IWL_CMD_QUEUE_NUM) len += IWL_MAX_SCAN_SIZE; txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); if (!txq->cmd) return -ENOMEM; - rc = iwl_tx_queue_alloc(priv, txq, txq_id); + /* Alloc driver data array and TFD circular buffer */ + rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); if (rc) { pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); @@ -341,26 +370,29 @@ int iwl_tx_queue_init(struct iwl_priv *priv, txq->need_update = 0; /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ + * iwl4965_queue_inc_wrap and iwl4965_queue_dec_wrap are broken. */ BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); - iwl_hw_tx_queue_init(priv, txq); + /* Initialize queue's high/low-water marks, and head/tail indexes */ + iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); + + /* Tell device where to find queue */ + iwl4965_hw_tx_queue_init(priv, txq); return 0; } /** - * iwl_tx_queue_free - Deallocate DMA queue. + * iwl4965_tx_queue_free - Deallocate DMA queue. * @txq: Transmit queue to deallocate. * * Empty queue by removing and destroying all BD's. - * Free all buffers. txq itself is not freed. - * + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. */ -void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) +void iwl4965_tx_queue_free(struct iwl4965_priv *priv, struct iwl4965_tx_queue *txq) { - struct iwl_queue *q = &txq->q; + struct iwl4965_queue *q = &txq->q; struct pci_dev *dev = priv->pci_dev; int len; @@ -368,45 +400,48 @@ void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq) return; /* first, empty all BD's */ - for (; q->first_empty != q->last_used; - q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) - iwl_hw_txq_free_tfd(priv, txq); + for (; q->write_ptr != q->read_ptr; + q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) + iwl4965_hw_txq_free_tfd(priv, txq); - len = sizeof(struct iwl_cmd) * q->n_window; + len = sizeof(struct iwl4965_cmd) * q->n_window; if (q->id == IWL_CMD_QUEUE_NUM) len += IWL_MAX_SCAN_SIZE; + /* De-alloc array of command/tx buffers */ pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); - /* free buffers belonging to queue itself */ + /* De-alloc circular buffer of TFDs */ if (txq->q.n_bd) - pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) * + pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * txq->q.n_bd, txq->bd, txq->q.dma_addr); + /* De-alloc array of per-TFD driver data */ if (txq->txb) { kfree(txq->txb); txq->txb = NULL; } - /* 0 fill whole structure */ + /* 0-fill queue descriptor structure */ memset(txq, 0, sizeof(*txq)); } -const u8 BROADCAST_ADDR[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /*************** STATION TABLE MANAGEMENT **** - * - * NOTE: This needs to be overhauled to better synchronize between - * how the iwl-4965.c is using iwl_hw_find_station vs. iwl-3945.c - * - * mac80211 should also be examined to determine if sta_info is duplicating + * mac80211 should be examined to determine if sta_info is duplicating * the functionality provided here */ /**************************************************************/ -#if 0 /* temparary disable till we add real remove station */ -static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) +#if 0 /* temporary disable till we add real remove station */ +/** + * iwl4965_remove_station - Remove driver's knowledge of station. + * + * NOTE: This does not remove station from device's station table. + */ +static u8 iwl4965_remove_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) { int index = IWL_INVALID_STATION; int i; @@ -443,7 +478,12 @@ out: } #endif -static void iwl_clear_stations_table(struct iwl_priv *priv) +/** + * iwl4965_clear_stations_table - Clear the driver's station table + * + * NOTE: This does not clear or otherwise alter the device's station table. + */ +static void iwl4965_clear_stations_table(struct iwl4965_priv *priv) { unsigned long flags; @@ -455,11 +495,15 @@ static void iwl_clear_stations_table(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->sta_lock, flags); } -u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) +/** + * iwl4965_add_station_flags - Add station to tables in driver and device + */ +u8 iwl4965_add_station_flags(struct iwl4965_priv *priv, const u8 *addr, + int is_ap, u8 flags, void *ht_data) { int i; int index = IWL_INVALID_STATION; - struct iwl_station_entry *station; + struct iwl4965_station_entry *station; unsigned long flags_spin; DECLARE_MAC_BUF(mac); @@ -482,8 +526,8 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) } - /* These twh conditions has the same outcome but keep them separate - since they have different meaning */ + /* These two conditions have the same outcome, but keep them separate + since they have different meanings */ if (unlikely(index == IWL_INVALID_STATION)) { spin_unlock_irqrestore(&priv->sta_lock, flags_spin); return index; @@ -501,28 +545,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags) station->used = 1; priv->num_stations++; - memset(&station->sta, 0, sizeof(struct iwl_addsta_cmd)); + /* Set up the REPLY_ADD_STA command to send to device */ + memset(&station->sta, 0, sizeof(struct iwl4965_addsta_cmd)); memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = index; station->sta.station_flags = 0; -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT /* BCAST station and IBSS stations do not work in HT mode */ if (index != priv->hw_setting.bcast_sta_id && priv->iw_mode != IEEE80211_IF_TYPE_IBSS) - iwl4965_set_ht_add_station(priv, index); -#endif /*CONFIG_IWLWIFI_HT*/ + iwl4965_set_ht_add_station(priv, index, + (struct ieee80211_ht_info *) ht_data); +#endif /*CONFIG_IWL4965_HT*/ spin_unlock_irqrestore(&priv->sta_lock, flags_spin); - iwl_send_add_station(priv, &station->sta, flags); + + /* Add station to device's station table */ + iwl4965_send_add_station(priv, &station->sta, flags); return index; } /*************** DRIVER STATUS FUNCTIONS *****/ -static inline int iwl_is_ready(struct iwl_priv *priv) +static inline int iwl4965_is_ready(struct iwl4965_priv *priv) { /* The adapter is 'ready' if READY and GEO_CONFIGURED bits are * set but EXIT_PENDING is not */ @@ -531,29 +579,29 @@ static inline int iwl_is_ready(struct iwl_priv *priv) !test_bit(STATUS_EXIT_PENDING, &priv->status); } -static inline int iwl_is_alive(struct iwl_priv *priv) +static inline int iwl4965_is_alive(struct iwl4965_priv *priv) { return test_bit(STATUS_ALIVE, &priv->status); } -static inline int iwl_is_init(struct iwl_priv *priv) +static inline int iwl4965_is_init(struct iwl4965_priv *priv) { return test_bit(STATUS_INIT, &priv->status); } -static inline int iwl_is_rfkill(struct iwl_priv *priv) +static inline int iwl4965_is_rfkill(struct iwl4965_priv *priv) { return test_bit(STATUS_RF_KILL_HW, &priv->status) || test_bit(STATUS_RF_KILL_SW, &priv->status); } -static inline int iwl_is_ready_rf(struct iwl_priv *priv) +static inline int iwl4965_is_ready_rf(struct iwl4965_priv *priv) { - if (iwl_is_rfkill(priv)) + if (iwl4965_is_rfkill(priv)) return 0; - return iwl_is_ready(priv); + return iwl4965_is_ready(priv); } /*************** HOST COMMAND QUEUE FUNCTIONS *****/ @@ -618,7 +666,7 @@ static const char *get_cmd_string(u8 cmd) #define HOST_COMPLETE_TIMEOUT (HZ / 2) /** - * iwl_enqueue_hcmd - enqueue a uCode command + * iwl4965_enqueue_hcmd - enqueue a uCode command * @priv: device private data point * @cmd: a point to the ucode command structure * @@ -626,13 +674,13 @@ static const char *get_cmd_string(u8 cmd) * failed. On success, it turns the index (> 0) of command in the * command queue. */ -static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl4965_enqueue_hcmd(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; - struct iwl_queue *q = &txq->q; - struct iwl_tfd_frame *tfd; + struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl4965_queue *q = &txq->q; + struct iwl4965_tfd_frame *tfd; u32 *control_flags; - struct iwl_cmd *out_cmd; + struct iwl4965_cmd *out_cmd; u32 idx; u16 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); dma_addr_t phys_addr; @@ -645,19 +693,19 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && !(cmd->meta.flags & CMD_SIZE_HUGE)); - if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { + if (iwl4965_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERROR("No space for Tx\n"); return -ENOSPC; } spin_lock_irqsave(&priv->hcmd_lock, flags); - tfd = &txq->bd[q->first_empty]; + tfd = &txq->bd[q->write_ptr]; memset(tfd, 0, sizeof(*tfd)); control_flags = (u32 *) tfd; - idx = get_cmd_index(q, q->first_empty, cmd->meta.flags & CMD_SIZE_HUGE); + idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); out_cmd = &txq->cmd[idx]; out_cmd->hdr.cmd = cmd->id; @@ -669,30 +717,34 @@ static int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) out_cmd->hdr.flags = 0; out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | - INDEX_TO_SEQ(q->first_empty)); + INDEX_TO_SEQ(q->write_ptr)); if (out_cmd->meta.flags & CMD_SIZE_HUGE) out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME); phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx + - offsetof(struct iwl_cmd, hdr); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); + offsetof(struct iwl4965_cmd, hdr); + iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size); IWL_DEBUG_HC("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->first_empty, idx, IWL_CMD_QUEUE_NUM); + fix_size, q->write_ptr, idx, IWL_CMD_QUEUE_NUM); txq->need_update = 1; + + /* Set up entry in queue's byte count circular buffer */ ret = iwl4965_tx_queue_update_wr_ptr(priv, txq, 0); - q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd); - iwl_tx_queue_update_write_ptr(priv, txq); + + /* Increment and update queue's write index */ + q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl4965_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->hcmd_lock, flags); return ret ? ret : idx; } -int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl4965_send_cmd_async(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd) { int ret; @@ -707,16 +759,16 @@ int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EBUSY; - ret = iwl_enqueue_hcmd(priv, cmd); + ret = iwl4965_enqueue_hcmd(priv, cmd); if (ret < 0) { - IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n", + IWL_ERROR("Error sending %s: iwl4965_enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); return ret; } return 0; } -int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +static int iwl4965_send_cmd_sync(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd) { int cmd_idx; int ret; @@ -738,10 +790,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (cmd->meta.flags & CMD_WANT_SKB) cmd->meta.source = &cmd->meta; - cmd_idx = iwl_enqueue_hcmd(priv, cmd); + cmd_idx = iwl4965_enqueue_hcmd(priv, cmd); if (cmd_idx < 0) { ret = cmd_idx; - IWL_ERROR("Error sending %s: iwl_enqueue_hcmd failed: %d\n", + IWL_ERROR("Error sending %s: iwl4965_enqueue_hcmd failed: %d\n", get_cmd_string(cmd->id), ret); goto out; } @@ -785,7 +837,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) cancel: if (cmd->meta.flags & CMD_WANT_SKB) { - struct iwl_cmd *qcmd; + struct iwl4965_cmd *qcmd; /* Cancel the CMD_WANT_SKB flag for the cmd in the * TX cmd queue. Otherwise in case the cmd comes @@ -804,64 +856,75 @@ out: return ret; } -int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) +int iwl4965_send_cmd(struct iwl4965_priv *priv, struct iwl4965_host_cmd *cmd) { - /* A command can not be asynchronous AND expect an SKB to be set. */ - BUG_ON((cmd->meta.flags & CMD_ASYNC) && - (cmd->meta.flags & CMD_WANT_SKB)); - if (cmd->meta.flags & CMD_ASYNC) - return iwl_send_cmd_async(priv, cmd); + return iwl4965_send_cmd_async(priv, cmd); - return iwl_send_cmd_sync(priv, cmd); + return iwl4965_send_cmd_sync(priv, cmd); } -int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data) +int iwl4965_send_cmd_pdu(struct iwl4965_priv *priv, u8 id, u16 len, const void *data) { - struct iwl_host_cmd cmd = { + struct iwl4965_host_cmd cmd = { .id = id, .len = len, .data = data, }; - return iwl_send_cmd_sync(priv, &cmd); + return iwl4965_send_cmd_sync(priv, &cmd); } -static int __must_check iwl_send_cmd_u32(struct iwl_priv *priv, u8 id, u32 val) +static int __must_check iwl4965_send_cmd_u32(struct iwl4965_priv *priv, u8 id, u32 val) { - struct iwl_host_cmd cmd = { + struct iwl4965_host_cmd cmd = { .id = id, .len = sizeof(val), .data = &val, }; - return iwl_send_cmd_sync(priv, &cmd); + return iwl4965_send_cmd_sync(priv, &cmd); } -int iwl_send_statistics_request(struct iwl_priv *priv) +int iwl4965_send_statistics_request(struct iwl4965_priv *priv) { - return iwl_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0); + return iwl4965_send_cmd_u32(priv, REPLY_STATISTICS_CMD, 0); } /** - * iwl_rxon_add_station - add station into station table. + * iwl4965_rxon_add_station - add station into station table. * * there is only one AP station with id= IWL_AP_ID - * NOTE: mutex must be held before calling the this fnction -*/ -static int iwl_rxon_add_station(struct iwl_priv *priv, + * NOTE: mutex must be held before calling this fnction + */ +static int iwl4965_rxon_add_station(struct iwl4965_priv *priv, const u8 *addr, int is_ap) { u8 sta_id; - sta_id = iwl_add_station(priv, addr, is_ap, 0); + /* Add station to device's station table */ +#ifdef CONFIG_IWL4965_HT + struct ieee80211_conf *conf = &priv->hw->conf; + struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; + + if ((is_ap) && + (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && + (priv->iw_mode == IEEE80211_IF_TYPE_STA)) + sta_id = iwl4965_add_station_flags(priv, addr, is_ap, + 0, cur_ht_config); + else +#endif /* CONFIG_IWL4965_HT */ + sta_id = iwl4965_add_station_flags(priv, addr, is_ap, + 0, NULL); + + /* Set up default rate scaling table in device's station table */ iwl4965_add_station(priv, addr, is_ap); return sta_id; } /** - * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON + * iwl4965_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 @@ -870,9 +933,10 @@ static int iwl_rxon_add_station(struct iwl_priv *priv, * NOTE: Does not commit to the hardware; it sets appropriate bit fields * in the staging RXON flag structure based on the phymode */ -static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel) +static int iwl4965_set_rxon_channel(struct iwl4965_priv *priv, u8 phymode, + u16 channel) { - if (!iwl_get_channel_info(priv, phymode, channel)) { + if (!iwl4965_get_channel_info(priv, phymode, channel)) { IWL_DEBUG_INFO("Could not set channel to %d [%d]\n", channel, phymode); return -EINVAL; @@ -896,13 +960,13 @@ static int iwl_set_rxon_channel(struct iwl_priv *priv, u8 phymode, u16 channel) } /** - * iwl_check_rxon_cmd - validate RXON structure is valid + * iwl4965_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 */ -static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon) +static int iwl4965_check_rxon_cmd(struct iwl4965_rxon_cmd *rxon) { int error = 0; int counter = 1; @@ -962,21 +1026,21 @@ static int iwl_check_rxon_cmd(struct iwl_rxon_cmd *rxon) le16_to_cpu(rxon->channel)); if (error) { - IWL_ERROR("Not a valid iwl_rxon_assoc_cmd field values\n"); + IWL_ERROR("Not a valid iwl4965_rxon_assoc_cmd field values\n"); return -1; } return 0; } /** - * iwl_full_rxon_required - determine if RXON_ASSOC can be used in RXON commit - * @priv: staging_rxon is comapred to active_rxon + * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed + * @priv: staging_rxon is compared to active_rxon * - * If the RXON structure is changing sufficient to require a new - * tune or to clear and reset the RXON_FILTER_ASSOC_MSK then return 1 - * to indicate a new tune is required. + * If the RXON structure is changing enough to require a new tune, + * 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. */ -static int iwl_full_rxon_required(struct iwl_priv *priv) +static int iwl4965_full_rxon_required(struct iwl4965_priv *priv) { /* These items are only settable from the full RXON command */ @@ -1016,19 +1080,19 @@ static int iwl_full_rxon_required(struct iwl_priv *priv) return 0; } -static int iwl_send_rxon_assoc(struct iwl_priv *priv) +static int iwl4965_send_rxon_assoc(struct iwl4965_priv *priv) { int rc = 0; - struct iwl_rx_packet *res = NULL; - struct iwl_rxon_assoc_cmd rxon_assoc; - struct iwl_host_cmd cmd = { + struct iwl4965_rx_packet *res = NULL; + struct iwl4965_rxon_assoc_cmd rxon_assoc; + struct iwl4965_host_cmd cmd = { .id = REPLY_RXON_ASSOC, .len = sizeof(rxon_assoc), .meta.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 iwl4965_rxon_cmd *rxon1 = &priv->staging_rxon; + const struct iwl4965_rxon_cmd *rxon2 = &priv->active_rxon; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1054,11 +1118,11 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv) priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl4965_send_cmd_sync(priv, &cmd); if (rc) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_RXON_ASSOC command\n"); rc = -EIO; @@ -1071,37 +1135,37 @@ static int iwl_send_rxon_assoc(struct iwl_priv *priv) } /** - * iwl_commit_rxon - commit staging_rxon to hardware + * iwl4965_commit_rxon - commit staging_rxon to hardware * - * The RXON command in staging_rxon is commited to the hardware and + * 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. */ -static int iwl_commit_rxon(struct iwl_priv *priv) +static int iwl4965_commit_rxon(struct iwl4965_priv *priv) { /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + struct iwl4965_rxon_cmd *active_rxon = (void *)&priv->active_rxon; DECLARE_MAC_BUF(mac); int rc = 0; - if (!iwl_is_alive(priv)) + if (!iwl4965_is_alive(priv)) return -1; /* always get timestamp with Rx frame */ priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; - rc = iwl_check_rxon_cmd(&priv->staging_rxon); + rc = iwl4965_check_rxon_cmd(&priv->staging_rxon); if (rc) { IWL_ERROR("Invalid RXON configuration. Not committing.\n"); return -EINVAL; } /* If we don't need to send a full RXON, we can use - * iwl_rxon_assoc_cmd which is used to reconfigure filter + * iwl4965_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 (!iwl4965_full_rxon_required(priv)) { + rc = iwl4965_send_rxon_assoc(priv); if (rc) { IWL_ERROR("Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1116,25 +1180,25 @@ static int iwl_commit_rxon(struct iwl_priv *priv) /* station table will be cleared */ priv->assoc_station_added = 0; -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT; if (!priv->error_recovering) priv->start_calib = 0; iwl4965_init_sensitivity(priv, CMD_ASYNC, 1); -#endif /* CONFIG_IWLWIFI_SENSITIVITY */ +#endif /* CONFIG_IWL4965_SENSITIVITY */ /* If we are currently associated and the new config requires * 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) && + if (iwl4965_is_associated(priv) && (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) { IWL_DEBUG_INFO("Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), + rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl4965_rxon_cmd), &priv->active_rxon); /* If the mask clearing failed then we set @@ -1157,35 +1221,35 @@ static int iwl_commit_rxon(struct iwl_priv *priv) print_mac(mac, priv->staging_rxon.bssid_addr)); /* Apply the new configuration */ - rc = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON, + sizeof(struct iwl4965_rxon_cmd), &priv->staging_rxon); if (rc) { IWL_ERROR("Error setting new configuration (%d).\n", rc); return rc; } - iwl_clear_stations_table(priv); + iwl4965_clear_stations_table(priv); -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY if (!priv->error_recovering) priv->start_calib = 0; priv->sensitivity_data.state = IWL_SENS_CALIB_NEED_REINIT; iwl4965_init_sensitivity(priv, CMD_ASYNC, 1); -#endif /* CONFIG_IWLWIFI_SENSITIVITY */ +#endif /* CONFIG_IWL4965_SENSITIVITY */ memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = iwl_hw_reg_send_txpower(priv); + rc = iwl4965_hw_reg_send_txpower(priv); if (rc) { IWL_ERROR("Error setting Tx power (%d).\n", rc); return rc; } /* Add the broadcast address so we can send broadcast frames */ - if (iwl_rxon_add_station(priv, BROADCAST_ADDR, 0) == + if (iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0) == IWL_INVALID_STATION) { IWL_ERROR("Error adding BROADCAST address for transmit.\n"); return -EIO; @@ -1193,9 +1257,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) /* If we have set the ASSOC_MSK and we are in BSS mode then * add the IWL_AP_ID to the station rate table */ - if (iwl_is_associated(priv) && + if (iwl4965_is_associated(priv) && (priv->iw_mode == IEEE80211_IF_TYPE_STA)) { - if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) + if (iwl4965_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1) == IWL_INVALID_STATION) { IWL_ERROR("Error adding AP address for transmit.\n"); return -EIO; @@ -1206,9 +1270,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv) return 0; } -static int iwl_send_bt_config(struct iwl_priv *priv) +static int iwl4965_send_bt_config(struct iwl4965_priv *priv) { - struct iwl_bt_cmd bt_cmd = { + struct iwl4965_bt_cmd bt_cmd = { .flags = 3, .lead_time = 0xAA, .max_kill = 1, @@ -1216,15 +1280,15 @@ static int iwl_send_bt_config(struct iwl_priv *priv) .kill_cts_mask = 0, }; - return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, - sizeof(struct iwl_bt_cmd), &bt_cmd); + return iwl4965_send_cmd_pdu(priv, REPLY_BT_CONFIG, + sizeof(struct iwl4965_bt_cmd), &bt_cmd); } -static int iwl_send_scan_abort(struct iwl_priv *priv) +static int iwl4965_send_scan_abort(struct iwl4965_priv *priv) { int rc = 0; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { + struct iwl4965_rx_packet *res; + struct iwl4965_host_cmd cmd = { .id = REPLY_SCAN_ABORT_CMD, .meta.flags = CMD_WANT_SKB, }; @@ -1237,13 +1301,13 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) return 0; } - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl4965_send_cmd_sync(priv, &cmd); if (rc) { clear_bit(STATUS_SCAN_ABORTING, &priv->status); return rc; } - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; if (res->u.status != CAN_ABORT_STATUS) { /* The scan abort will return 1 for success or * 2 for "failure". A failure condition can be @@ -1261,8 +1325,8 @@ static int iwl_send_scan_abort(struct iwl_priv *priv) return rc; } -static int iwl_card_state_sync_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, +static int iwl4965_card_state_sync_callback(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct sk_buff *skb) { return 1; @@ -1271,16 +1335,16 @@ static int iwl_card_state_sync_callback(struct iwl_priv *priv, /* * CARD_STATE_CMD * - * Use: Sets the internal card state to enable, disable, or halt + * 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. */ -static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) +static int iwl4965_send_card_state(struct iwl4965_priv *priv, u32 flags, u8 meta_flag) { - struct iwl_host_cmd cmd = { + struct iwl4965_host_cmd cmd = { .id = REPLY_CARD_STATE_CMD, .len = sizeof(u32), .data = &flags, @@ -1288,22 +1352,22 @@ static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) }; if (meta_flag & CMD_ASYNC) - cmd.meta.u.callback = iwl_card_state_sync_callback; + cmd.meta.u.callback = iwl4965_card_state_sync_callback; - return iwl_send_cmd(priv, &cmd); + return iwl4965_send_cmd(priv, &cmd); } -static int iwl_add_sta_sync_callback(struct iwl_priv *priv, - struct iwl_cmd *cmd, struct sk_buff *skb) +static int iwl4965_add_sta_sync_callback(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct sk_buff *skb) { - struct iwl_rx_packet *res = NULL; + struct iwl4965_rx_packet *res = NULL; if (!skb) { IWL_ERROR("Error: Response NULL in REPLY_ADD_STA.\n"); return 1; } - res = (struct iwl_rx_packet *)skb->data; + res = (struct iwl4965_rx_packet *)skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", res->hdr.flags); @@ -1321,29 +1385,29 @@ static int iwl_add_sta_sync_callback(struct iwl_priv *priv, return 1; } -int iwl_send_add_station(struct iwl_priv *priv, - struct iwl_addsta_cmd *sta, u8 flags) +int iwl4965_send_add_station(struct iwl4965_priv *priv, + struct iwl4965_addsta_cmd *sta, u8 flags) { - struct iwl_rx_packet *res = NULL; + struct iwl4965_rx_packet *res = NULL; int rc = 0; - struct iwl_host_cmd cmd = { + struct iwl4965_host_cmd cmd = { .id = REPLY_ADD_STA, - .len = sizeof(struct iwl_addsta_cmd), + .len = sizeof(struct iwl4965_addsta_cmd), .meta.flags = flags, .data = sta, }; if (flags & CMD_ASYNC) - cmd.meta.u.callback = iwl_add_sta_sync_callback; + cmd.meta.u.callback = iwl4965_add_sta_sync_callback; else cmd.meta.flags |= CMD_WANT_SKB; - rc = iwl_send_cmd(priv, &cmd); + rc = iwl4965_send_cmd(priv, &cmd); if (rc || (flags & CMD_ASYNC)) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_ADD_STA (0x%08X)\n", res->hdr.flags); @@ -1368,7 +1432,7 @@ int iwl_send_add_station(struct iwl_priv *priv, return rc; } -static int iwl_update_sta_key_info(struct iwl_priv *priv, +static int iwl4965_update_sta_key_info(struct iwl4965_priv *priv, struct ieee80211_key_conf *keyconf, u8 sta_id) { @@ -1384,7 +1448,6 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv, break; case ALG_TKIP: case ALG_WEP: - return -EINVAL; default: return -EINVAL; } @@ -1403,28 +1466,28 @@ static int iwl_update_sta_key_info(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n"); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); return 0; } -static int iwl_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) +static int iwl4965_clear_sta_key_info(struct iwl4965_priv *priv, u8 sta_id) { unsigned long flags; spin_lock_irqsave(&priv->sta_lock, flags); - memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, sizeof(struct iwl_keyinfo)); + memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl4965_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; priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; spin_unlock_irqrestore(&priv->sta_lock, flags); IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); - iwl_send_add_station(priv, &priv->stations[sta_id].sta, 0); + iwl4965_send_add_station(priv, &priv->stations[sta_id].sta, 0); return 0; } -static void iwl_clear_free_frames(struct iwl_priv *priv) +static void iwl4965_clear_free_frames(struct iwl4965_priv *priv) { struct list_head *element; @@ -1434,7 +1497,7 @@ static void iwl_clear_free_frames(struct iwl_priv *priv) while (!list_empty(&priv->free_frames)) { element = priv->free_frames.next; list_del(element); - kfree(list_entry(element, struct iwl_frame, list)); + kfree(list_entry(element, struct iwl4965_frame, list)); priv->frames_count--; } @@ -1445,9 +1508,9 @@ static void iwl_clear_free_frames(struct iwl_priv *priv) } } -static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) +static struct iwl4965_frame *iwl4965_get_free_frame(struct iwl4965_priv *priv) { - struct iwl_frame *frame; + struct iwl4965_frame *frame; struct list_head *element; if (list_empty(&priv->free_frames)) { frame = kzalloc(sizeof(*frame), GFP_KERNEL); @@ -1462,21 +1525,21 @@ static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv) element = priv->free_frames.next; list_del(element); - return list_entry(element, struct iwl_frame, list); + return list_entry(element, struct iwl4965_frame, list); } -static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) +static void iwl4965_free_frame(struct iwl4965_priv *priv, struct iwl4965_frame *frame) { memset(frame, 0, sizeof(*frame)); list_add(&frame->list, &priv->free_frames); } -unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, +unsigned int iwl4965_fill_beacon_frame(struct iwl4965_priv *priv, struct ieee80211_hdr *hdr, const u8 *dest, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon || + if (!iwl4965_is_associated(priv) || !priv->ibss_beacon || ((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) && (priv->iw_mode != IEEE80211_IF_TYPE_AP))) return 0; @@ -1489,10 +1552,11 @@ unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, return priv->ibss_beacon->len; } -int iwl_rate_index_from_plcp(int plcp) +int iwl4965_rate_index_from_plcp(int plcp) { int i = 0; + /* 4965 HT rate format */ if (plcp & RATE_MCS_HT_MSK) { i = (plcp & 0xff); @@ -1506,35 +1570,37 @@ int iwl_rate_index_from_plcp(int plcp) if ((i >= IWL_FIRST_OFDM_RATE) && (i <= IWL_LAST_OFDM_RATE)) return i; + + /* 4965 legacy rate format, search for match in table */ } else { - for (i = 0; i < ARRAY_SIZE(iwl_rates); i++) - if (iwl_rates[i].plcp == (plcp &0xFF)) + for (i = 0; i < ARRAY_SIZE(iwl4965_rates); i++) + if (iwl4965_rates[i].plcp == (plcp &0xFF)) return i; } return -1; } -static u8 iwl_rate_get_lowest_plcp(int rate_mask) +static u8 iwl4965_rate_get_lowest_plcp(int rate_mask) { u8 i; for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; - i = iwl_rates[i].next_ieee) { + i = iwl4965_rates[i].next_ieee) { if (rate_mask & (1 << i)) - return iwl_rates[i].plcp; + return iwl4965_rates[i].plcp; } return IWL_RATE_INVALID; } -static int iwl_send_beacon_cmd(struct iwl_priv *priv) +static int iwl4965_send_beacon_cmd(struct iwl4965_priv *priv) { - struct iwl_frame *frame; + struct iwl4965_frame *frame; unsigned int frame_size; int rc; u8 rate; - frame = iwl_get_free_frame(priv); + frame = iwl4965_get_free_frame(priv); if (!frame) { IWL_ERROR("Could not obtain free frame buffer for beacon " @@ -1543,22 +1609,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) } if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) { - rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & + rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xFF0); if (rate == IWL_INVALID_RATE) rate = IWL_RATE_6M_PLCP; } else { - rate = iwl_rate_get_lowest_plcp(priv->active_rate_basic & 0xF); + rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xF); if (rate == IWL_INVALID_RATE) rate = IWL_RATE_1M_PLCP; } - frame_size = iwl_hw_get_beacon_cmd(priv, frame, rate); + frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate); - rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, + rc = iwl4965_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size, &frame->u.cmd[0]); - iwl_free_frame(priv, frame); + iwl4965_free_frame(priv, frame); return rc; } @@ -1569,22 +1635,22 @@ static int iwl_send_beacon_cmd(struct iwl_priv *priv) * ******************************************************************************/ -static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac) +static void get_eeprom_mac(struct iwl4965_priv *priv, u8 *mac) { memcpy(mac, priv->eeprom.mac_address, 6); } /** - * iwl_eeprom_init - read EEPROM contents + * iwl4965_eeprom_init - read EEPROM contents * - * Load the EEPROM from adapter into priv->eeprom + * Load the EEPROM contents from adapter into priv->eeprom * * NOTE: This routine uses the non-debug IO access functions. */ -int iwl_eeprom_init(struct iwl_priv *priv) +int iwl4965_eeprom_init(struct iwl4965_priv *priv) { u16 *e = (u16 *)&priv->eeprom; - u32 gp = iwl_read32(priv, CSR_EEPROM_GP); + u32 gp = iwl4965_read32(priv, CSR_EEPROM_GP); u32 r; int sz = sizeof(priv->eeprom); int rc; @@ -1602,20 +1668,21 @@ int iwl_eeprom_init(struct iwl_priv *priv) return -ENOENT; } - rc = iwl_eeprom_aqcuire_semaphore(priv); + /* Make sure driver (instead of uCode) is allowed to read EEPROM */ + rc = iwl4965_eeprom_acquire_semaphore(priv); if (rc < 0) { - IWL_ERROR("Failed to aqcuire EEPROM semaphore.\n"); + IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); return -ENOENT; } /* eeprom is an array of 16bit values */ for (addr = 0; addr < sz; addr += sizeof(u16)) { - _iwl_write32(priv, CSR_EEPROM_REG, addr << 1); - _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); + _iwl4965_write32(priv, CSR_EEPROM_REG, addr << 1); + _iwl4965_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD); for (i = 0; i < IWL_EEPROM_ACCESS_TIMEOUT; i += IWL_EEPROM_ACCESS_DELAY) { - r = _iwl_read_restricted(priv, CSR_EEPROM_REG); + r = _iwl4965_read_direct32(priv, CSR_EEPROM_REG); if (r & CSR_EEPROM_REG_READ_VALID_MSK) break; udelay(IWL_EEPROM_ACCESS_DELAY); @@ -1631,7 +1698,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) rc = 0; done: - iwl_eeprom_release_semaphore(priv); + iwl4965_eeprom_release_semaphore(priv); return rc; } @@ -1640,22 +1707,20 @@ done: * Misc. internal state and helper functions * ******************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG /** - * iwl_report_frame - dump frame to syslog during debug sessions + * iwl4965_report_frame - dump frame to syslog during debug sessions * - * hack this function to show different aspects of received frames, + * You may hack this function to show different aspects of received frames, * including selective frame dumps. * group100 parameter selects whether to show 1 out of 100 good frames. * - * TODO: ieee80211_hdr stuff is common to 3945 and 4965, so frame type - * info output is okay, but some of this stuff (e.g. iwl_rx_frame_stats) - * is 3945-specific and gives bad output for 4965. Need to split the - * functionality, keep common stuff here. + * TODO: This was originally written for 3945, need to audit for + * proper operation with 4965. */ -void iwl_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, +void iwl4965_report_frame(struct iwl4965_priv *priv, + struct iwl4965_rx_packet *pkt, struct ieee80211_hdr *header, int group100) { u32 to_us; @@ -1677,9 +1742,9 @@ void iwl_report_frame(struct iwl_priv *priv, u8 agc; u16 sig_avg; u16 noise_diff; - struct iwl_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); - struct iwl_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); - struct iwl_rx_frame_end *rx_end = IWL_RX_END(pkt); + struct iwl4965_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt); + struct iwl4965_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt); + struct iwl4965_rx_frame_end *rx_end = IWL_RX_END(pkt); u8 *data = IWL_RX_DATA(pkt); /* MAC header */ @@ -1755,11 +1820,11 @@ void iwl_report_frame(struct iwl_priv *priv, else title = "Frame"; - rate = iwl_rate_index_from_plcp(rate_sym); + rate = iwl4965_rate_index_from_plcp(rate_sym); if (rate == -1) rate = 0; else - rate = iwl_rates[rate].ieee / 2; + rate = iwl4965_rates[rate].ieee / 2; /* print frame summary. * MAC addresses show just the last byte (for brevity), @@ -1781,25 +1846,25 @@ void iwl_report_frame(struct iwl_priv *priv, } } if (print_dump) - iwl_print_hex_dump(IWL_DL_RX, data, length); + iwl4965_print_hex_dump(IWL_DL_RX, data, length); } #endif -static void iwl_unset_hw_setting(struct iwl_priv *priv) +static void iwl4965_unset_hw_setting(struct iwl4965_priv *priv) { if (priv->hw_setting.shared_virt) pci_free_consistent(priv->pci_dev, - sizeof(struct iwl_shared), + sizeof(struct iwl4965_shared), priv->hw_setting.shared_virt, priv->hw_setting.shared_phys); } /** - * iwl_supported_rate_to_ie - fill in the supported rate in IE field + * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field * * return : set the bit for each supported rate insert in ie */ -static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, +static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, u16 basic_rate, int *left) { u16 ret_rates = 0, bit; @@ -1810,7 +1875,7 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { if (bit & supported_rate) { ret_rates |= bit; - rates[*cnt] = iwl_rates[i].ieee | + rates[*cnt] = iwl4965_rates[i].ieee | ((bit & basic_rate) ? 0x80 : 0x00); (*cnt)++; (*left)--; @@ -1823,22 +1888,25 @@ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, return ret_rates; } -#ifdef CONFIG_IWLWIFI_HT -void static iwl_set_ht_capab(struct ieee80211_hw *hw, - struct ieee80211_ht_capability *ht_cap, - u8 use_wide_chan); +#ifdef CONFIG_IWL4965_HT +void static iwl4965_set_ht_capab(struct ieee80211_hw *hw, + struct ieee80211_ht_cap *ht_cap, + u8 use_current_config); #endif /** - * iwl_fill_probe_req - fill in all required fields and IE for probe request + * iwl4965_fill_probe_req - fill in all required fields and IE for probe request */ -static u16 iwl_fill_probe_req(struct iwl_priv *priv, +static u16 iwl4965_fill_probe_req(struct iwl4965_priv *priv, struct ieee80211_mgmt *frame, int left, int is_direct) { int len = 0; u8 *pos = NULL; - u16 active_rates, ret_rates, cck_rates; + u16 active_rates, ret_rates, cck_rates, active_rate_basic; +#ifdef CONFIG_IWL4965_HT + struct ieee80211_hw_mode *mode; +#endif /* CONFIG_IWL4965_HT */ /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ @@ -1848,9 +1916,9 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, len += 24; frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, BROADCAST_ADDR, ETH_ALEN); + memcpy(frame->da, iwl4965_broadcast_addr, ETH_ALEN); memcpy(frame->sa, priv->mac_addr, ETH_ALEN); - memcpy(frame->bssid, BROADCAST_ADDR, ETH_ALEN); + memcpy(frame->bssid, iwl4965_broadcast_addr, ETH_ALEN); frame->seq_ctrl = 0; /* fill in our indirect SSID IE */ @@ -1888,17 +1956,19 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, *pos++ = WLAN_EID_SUPP_RATES; *pos = 0; - priv->active_rate = priv->rates_mask; - active_rates = priv->active_rate; - priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; + /* exclude 60M rate */ + active_rates = priv->rates_mask; + active_rates &= ~IWL_RATE_60M_MASK; + + active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; cck_rates = IWL_CCK_RATES_MASK & active_rates; - ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, - priv->active_rate_basic, &left); + ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates, + active_rate_basic, &left); active_rates &= ~ret_rates; - ret_rates = iwl_supported_rate_to_ie(pos, active_rates, - priv->active_rate_basic, &left); + ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates, + active_rate_basic, &left); active_rates &= ~ret_rates; len += 2 + *pos; @@ -1914,25 +1984,22 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* ... fill it in... */ *pos++ = WLAN_EID_EXT_SUPP_RATES; *pos = 0; - iwl_supported_rate_to_ie(pos, active_rates, - priv->active_rate_basic, &left); + iwl4965_supported_rate_to_ie(pos, active_rates, + active_rate_basic, &left); if (*pos > 0) len += 2 + *pos; -#ifdef CONFIG_IWLWIFI_HT - if (is_direct && priv->is_ht_enabled) { - u8 use_wide_chan = 1; - - if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ) - use_wide_chan = 0; +#ifdef CONFIG_IWL4965_HT + mode = priv->hw->conf.mode; + if (mode->ht_info.ht_supported) { pos += (*pos) + 1; *pos++ = WLAN_EID_HT_CAPABILITY; - *pos++ = sizeof(struct ieee80211_ht_capability); - iwl_set_ht_capab(NULL, (struct ieee80211_ht_capability *)pos, - use_wide_chan); - len += 2 + sizeof(struct ieee80211_ht_capability); + *pos++ = sizeof(struct ieee80211_ht_cap); + iwl4965_set_ht_capab(priv->hw, + (struct ieee80211_ht_cap *)pos, 0); + len += 2 + sizeof(struct ieee80211_ht_cap); } -#endif /*CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT */ fill_end: return (u16)len; @@ -1941,16 +2008,16 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* * QoS support */ -#ifdef CONFIG_IWLWIFI_QOS -static int iwl_send_qos_params_command(struct iwl_priv *priv, - struct iwl_qosparam_cmd *qos) +#ifdef CONFIG_IWL4965_QOS +static int iwl4965_send_qos_params_command(struct iwl4965_priv *priv, + struct iwl4965_qosparam_cmd *qos) { - return iwl_send_cmd_pdu(priv, REPLY_QOS_PARAM, - sizeof(struct iwl_qosparam_cmd), qos); + return iwl4965_send_cmd_pdu(priv, REPLY_QOS_PARAM, + sizeof(struct iwl4965_qosparam_cmd), qos); } -static void iwl_reset_qos(struct iwl_priv *priv) +static void iwl4965_reset_qos(struct iwl4965_priv *priv) { u16 cw_min = 15; u16 cw_max = 1023; @@ -2037,13 +2104,10 @@ static void iwl_reset_qos(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void iwl_activate_qos(struct iwl_priv *priv, u8 force) +static void iwl4965_activate_qos(struct iwl4965_priv *priv, u8 force) { unsigned long flags; - if (priv == NULL) - return; - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -2057,23 +2121,28 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force) !priv->qos_data.qos_cap.q_AP.txop_request) priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TXOP_TYPE_MSK; - if (priv->qos_data.qos_active) priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; +#ifdef CONFIG_IWL4965_HT + if (priv->current_ht_config.is_ht) + priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; +#endif /* CONFIG_IWL4965_HT */ + spin_unlock_irqrestore(&priv->lock, flags); - if (force || iwl_is_associated(priv)) { - IWL_DEBUG_QOS("send QoS cmd with Qos active %d \n", - priv->qos_data.qos_active); + if (force || iwl4965_is_associated(priv)) { + IWL_DEBUG_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n", + priv->qos_data.qos_active, + priv->qos_data.def_qos_parm.qos_flags); - iwl_send_qos_params_command(priv, + iwl4965_send_qos_params_command(priv, &(priv->qos_data.def_qos_parm)); } } -#endif /* CONFIG_IWLWIFI_QOS */ +#endif /* CONFIG_IWL4965_QOS */ /* * Power management (not Tx power!) functions */ @@ -2091,7 +2160,7 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force) /* default power management (not Tx power) table values */ /* for tim 0-10 */ -static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { +static struct iwl4965_power_vec_entry range_0[IWL_POWER_AC] = { {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(300), SLP_VEC(2, 4, 6, 7, 7)}, 0}, @@ -2101,7 +2170,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = { }; /* for tim > 10 */ -static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { +static struct iwl4965_power_vec_entry range_1[IWL_POWER_AC] = { {{NOSLP, SLP_TIMEOUT(0), SLP_TIMEOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, {{SLP, SLP_TIMEOUT(200), SLP_TIMEOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, @@ -2114,11 +2183,11 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = { SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} }; -int iwl_power_init_handle(struct iwl_priv *priv) +int iwl4965_power_init_handle(struct iwl4965_priv *priv) { int rc = 0, i; - struct iwl_power_mgr *pow_data; - int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC; + struct iwl4965_power_mgr *pow_data; + int size = sizeof(struct iwl4965_power_vec_entry) * IWL_POWER_AC; u16 pci_pm; IWL_DEBUG_POWER("Initialize power \n"); @@ -2137,7 +2206,7 @@ int iwl_power_init_handle(struct iwl_priv *priv) if (rc != 0) return 0; else { - struct iwl_powertable_cmd *cmd; + struct iwl4965_powertable_cmd *cmd; IWL_DEBUG_POWER("adjust power command flags\n"); @@ -2153,15 +2222,15 @@ int iwl_power_init_handle(struct iwl_priv *priv) return rc; } -static int iwl_update_power_cmd(struct iwl_priv *priv, - struct iwl_powertable_cmd *cmd, u32 mode) +static int iwl4965_update_power_cmd(struct iwl4965_priv *priv, + struct iwl4965_powertable_cmd *cmd, u32 mode) { int rc = 0, i; u8 skip; u32 max_sleep = 0; - struct iwl_power_vec_entry *range; + struct iwl4965_power_vec_entry *range; u8 period = 0; - struct iwl_power_mgr *pow_data; + struct iwl4965_power_mgr *pow_data; if (mode > IWL_POWER_INDEX_5) { IWL_DEBUG_POWER("Error invalid power mode \n"); @@ -2174,7 +2243,7 @@ static int iwl_update_power_cmd(struct iwl_priv *priv, else range = &pow_data->pwr_range_1[1]; - memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd)); + memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd)); #ifdef IWL_MAC80211_DISABLE if (priv->assoc_network != NULL) { @@ -2217,14 +2286,14 @@ static int iwl_update_power_cmd(struct iwl_priv *priv, return rc; } -static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) +static int iwl4965_send_power_mode(struct iwl4965_priv *priv, u32 mode) { - u32 final_mode = mode; + u32 uninitialized_var(final_mode); int rc; - struct iwl_powertable_cmd cmd; + struct iwl4965_powertable_cmd cmd; /* If on battery, set to 3, - * if plugged into AC power, set to CAM ("continuosly aware mode"), + * if plugged into AC power, set to CAM ("continuously aware mode"), * else user level */ switch (mode) { case IWL_POWER_BATTERY: @@ -2240,9 +2309,9 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) cmd.keep_alive_beacons = 0; - iwl_update_power_cmd(priv, &cmd, final_mode); + iwl4965_update_power_cmd(priv, &cmd, final_mode); - rc = iwl_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); + rc = iwl4965_send_cmd_pdu(priv, POWER_TABLE_CMD, sizeof(cmd), &cmd); if (final_mode == IWL_POWER_MODE_CAM) clear_bit(STATUS_POWER_PMI, &priv->status); @@ -2252,7 +2321,7 @@ static int iwl_send_power_mode(struct iwl_priv *priv, u32 mode) return rc; } -int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) +int iwl4965_is_network_packet(struct iwl4965_priv *priv, struct ieee80211_hdr *header) { /* Filter incoming packets to determine if they are targeted toward * this network, discarding packets coming from ourselves */ @@ -2282,7 +2351,7 @@ int iwl_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x -const char *iwl_get_tx_fail_reason(u32 status) +static const char *iwl4965_get_tx_fail_reason(u32 status) { switch (status & TX_STATUS_MSK) { case TX_STATUS_SUCCESS: @@ -2309,11 +2378,11 @@ const char *iwl_get_tx_fail_reason(u32 status) } /** - * iwl_scan_cancel - Cancel any currently executing HW scan + * iwl4965_scan_cancel - Cancel any currently executing HW scan * * NOTE: priv->mutex is not required before calling this function */ -static int iwl_scan_cancel(struct iwl_priv *priv) +static int iwl4965_scan_cancel(struct iwl4965_priv *priv) { if (!test_bit(STATUS_SCAN_HW, &priv->status)) { clear_bit(STATUS_SCANNING, &priv->status); @@ -2336,17 +2405,17 @@ static int iwl_scan_cancel(struct iwl_priv *priv) } /** - * iwl_scan_cancel_timeout - Cancel any currently executing HW scan + * iwl4965_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 */ -static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) +static int iwl4965_scan_cancel_timeout(struct iwl4965_priv *priv, unsigned long ms) { unsigned long now = jiffies; int ret; - ret = iwl_scan_cancel(priv); + ret = iwl4965_scan_cancel(priv); if (ret && ms) { mutex_unlock(&priv->mutex); while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && @@ -2360,7 +2429,7 @@ static int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) return ret; } -static void iwl_sequence_reset(struct iwl_priv *priv) +static void iwl4965_sequence_reset(struct iwl4965_priv *priv) { /* Reset ieee stats */ @@ -2371,13 +2440,13 @@ static void iwl_sequence_reset(struct iwl_priv *priv) priv->last_frag_num = -1; priv->last_packet_time = 0; - iwl_scan_cancel(priv); + iwl4965_scan_cancel(priv); } #define MAX_UCODE_BEACON_INTERVAL 4096 #define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA) -static __le16 iwl_adjust_beacon_interval(u16 beacon_val) +static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val) { u16 new_val = 0; u16 beacon_factor = 0; @@ -2390,7 +2459,7 @@ static __le16 iwl_adjust_beacon_interval(u16 beacon_val) return cpu_to_le16(new_val); } -static void iwl_setup_rxon_timing(struct iwl_priv *priv) +static void iwl4965_setup_rxon_timing(struct iwl4965_priv *priv) { u64 interval_tm_unit; u64 tsf, result; @@ -2420,14 +2489,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); priv->rxon_timing.beacon_interval = - iwl_adjust_beacon_interval( + iwl4965_adjust_beacon_interval( le16_to_cpu(priv->rxon_timing.beacon_interval)); } priv->rxon_timing.atim_window = 0; } else { priv->rxon_timing.beacon_interval = - iwl_adjust_beacon_interval(conf->beacon_int); + iwl4965_adjust_beacon_interval(conf->beacon_int); /* TODO: we need to get atim_window from upper stack * for now we set to 0 */ priv->rxon_timing.atim_window = 0; @@ -2446,14 +2515,14 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv) le16_to_cpu(priv->rxon_timing.atim_window)); } -static int iwl_scan_initiate(struct iwl_priv *priv) +static int iwl4965_scan_initiate(struct iwl4965_priv *priv) { if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { IWL_ERROR("APs don't scan.\n"); return 0; } - if (!iwl_is_ready_rf(priv)) { + if (!iwl4965_is_ready_rf(priv)) { IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); return -EIO; } @@ -2480,9 +2549,9 @@ static int iwl_scan_initiate(struct iwl_priv *priv) return 0; } -static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) +static int iwl4965_set_rxon_hwcrypto(struct iwl4965_priv *priv, int hw_decrypt) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl4965_rxon_cmd *rxon = &priv->staging_rxon; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -2492,7 +2561,7 @@ static int iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) return 0; } -static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) +static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode) { if (phymode == MODE_IEEE80211A) { priv->staging_rxon.flags &= @@ -2500,7 +2569,7 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) | RXON_FLG_CCK_MSK); priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { - /* Copied from iwl_bg_post_associate() */ + /* Copied from iwl4965_bg_post_associate() */ if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; else @@ -2516,11 +2585,11 @@ static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode) } /* - * initilize rxon structure with default values fromm eeprom + * initialize rxon structure with default values from eeprom */ -static void iwl_connection_init_rx_config(struct iwl_priv *priv) +static void iwl4965_connection_init_rx_config(struct iwl4965_priv *priv) { - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); @@ -2557,7 +2626,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif - ch_info = iwl_get_channel_info(priv, priv->phymode, + ch_info = iwl4965_get_channel_info(priv, priv->phymode, le16_to_cpu(priv->staging_rxon.channel)); if (!ch_info) @@ -2577,7 +2646,7 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) else priv->phymode = MODE_IEEE80211G; - iwl_set_flags_for_phymode(priv, priv->phymode); + iwl4965_set_flags_for_phymode(priv, priv->phymode); priv->staging_rxon.ofdm_basic_rates = (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; @@ -2593,15 +2662,12 @@ static void iwl_connection_init_rx_config(struct iwl_priv *priv) iwl4965_set_rxon_chain(priv); } -static int iwl_set_mode(struct iwl_priv *priv, int mode) +static int iwl4965_set_mode(struct iwl4965_priv *priv, int mode) { - if (!iwl_is_ready_rf(priv)) - return -EAGAIN; - if (mode == IEEE80211_IF_TYPE_IBSS) { - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, + ch_info = iwl4965_get_channel_info(priv, priv->phymode, le16_to_cpu(priv->staging_rxon.channel)); @@ -2612,32 +2678,36 @@ static int iwl_set_mode(struct iwl_priv *priv, int mode) } } + priv->iw_mode = mode; + + iwl4965_connection_init_rx_config(priv); + memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); + + iwl4965_clear_stations_table(priv); + + /* dont commit rxon if rf-kill is on*/ + if (!iwl4965_is_ready_rf(priv)) + return -EAGAIN; + cancel_delayed_work(&priv->scan_check); - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl4965_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); return -EAGAIN; } - priv->iw_mode = mode; - - iwl_connection_init_rx_config(priv); - memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); - - iwl_clear_stations_table(priv); - - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); return 0; } -static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv, +static void iwl4965_build_tx_cmd_hwcrypto(struct iwl4965_priv *priv, struct ieee80211_tx_control *ctl, - struct iwl_cmd *cmd, + struct iwl4965_cmd *cmd, struct sk_buff *skb_frag, int last_frag) { - struct iwl_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo; + struct iwl4965_hw_key *keyinfo = &priv->stations[ctl->key_idx].keyinfo; switch (keyinfo->alg) { case ALG_CCMP: @@ -2680,8 +2750,8 @@ static void iwl_build_tx_cmd_hwcrypto(struct iwl_priv *priv, /* * handle build REPLY_TX command notification. */ -static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, - struct iwl_cmd *cmd, +static void iwl4965_build_tx_cmd_basic(struct iwl4965_priv *priv, + struct iwl4965_cmd *cmd, struct ieee80211_tx_control *ctrl, struct ieee80211_hdr *hdr, int is_unicast, u8 std_id) @@ -2729,11 +2799,9 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) - cmd->cmd.tx.timeout.pm_frame_timeout = - cpu_to_le16(3); + cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); else - cmd->cmd.tx.timeout.pm_frame_timeout = - cpu_to_le16(2); + cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); } else cmd->cmd.tx.timeout.pm_frame_timeout = 0; @@ -2742,40 +2810,47 @@ static void iwl_build_tx_cmd_basic(struct iwl_priv *priv, cmd->cmd.tx.next_frame_len = 0; } -static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) +/** + * iwl4965_get_sta_id - Find station's index within station table + * + * If new IBSS station, create new entry in station table + */ +static int iwl4965_get_sta_id(struct iwl4965_priv *priv, + struct ieee80211_hdr *hdr) { int sta_id; u16 fc = le16_to_cpu(hdr->frame_control); DECLARE_MAC_BUF(mac); - /* If this frame is broadcast or not data then use the broadcast - * station id */ + /* If this frame is broadcast or management, use broadcast station id */ if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || is_multicast_ether_addr(hdr->addr1)) return priv->hw_setting.bcast_sta_id; switch (priv->iw_mode) { - /* If this frame is part of a BSS network (we're a station), then - * we use the AP's station id */ + /* If we are a client station in a BSS network, use the special + * AP station entry (that's the only station we communicate with) */ case IEEE80211_IF_TYPE_STA: return IWL_AP_ID; /* If we are an AP, then find the station, or use BCAST */ case IEEE80211_IF_TYPE_AP: - sta_id = iwl_hw_find_station(priv, hdr->addr1); + sta_id = iwl4965_hw_find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; return priv->hw_setting.bcast_sta_id; - /* If this frame is part of a IBSS network, then we use the - * target specific station id */ + /* If this frame is going out to an IBSS network, find the station, + * or create a new station table entry */ case IEEE80211_IF_TYPE_IBSS: - sta_id = iwl_hw_find_station(priv, hdr->addr1); + sta_id = iwl4965_hw_find_station(priv, hdr->addr1); if (sta_id != IWL_INVALID_STATION) return sta_id; - sta_id = iwl_add_station(priv, hdr->addr1, 0, CMD_ASYNC); + /* Create new station table entry */ + sta_id = iwl4965_add_station_flags(priv, hdr->addr1, + 0, CMD_ASYNC, NULL); if (sta_id != IWL_INVALID_STATION) return sta_id; @@ -2783,11 +2858,11 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) IWL_DEBUG_DROP("Station %s not in station map. " "Defaulting to broadcast...\n", print_mac(mac, hdr->addr1)); - iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); + iwl4965_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); return priv->hw_setting.bcast_sta_id; default: - IWL_WARNING("Unkown mode of operation: %d", priv->iw_mode); + IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode); return priv->hw_setting.bcast_sta_id; } } @@ -2795,18 +2870,18 @@ static int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) /* * start REPLY_TX command process */ -static int iwl_tx_skb(struct iwl_priv *priv, +static int iwl4965_tx_skb(struct iwl4965_priv *priv, struct sk_buff *skb, struct ieee80211_tx_control *ctl) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_tfd_frame *tfd; + struct iwl4965_tfd_frame *tfd; u32 *control_flags; int txq_id = ctl->queue; - struct iwl_tx_queue *txq = NULL; - struct iwl_queue *q = NULL; + struct iwl4965_tx_queue *txq = NULL; + struct iwl4965_queue *q = NULL; dma_addr_t phys_addr; dma_addr_t txcmd_phys; - struct iwl_cmd *out_cmd = NULL; + struct iwl4965_cmd *out_cmd = NULL; u16 len, idx, len_org; u8 id, hdr_len, unicast; u8 sta_id; @@ -2818,7 +2893,7 @@ static int iwl_tx_skb(struct iwl_priv *priv, int rc; spin_lock_irqsave(&priv->lock, flags); - if (iwl_is_rfkill(priv)) { + if (iwl4965_is_rfkill(priv)) { IWL_DEBUG_DROP("Dropping - RF KILL\n"); goto drop_unlock; } @@ -2838,7 +2913,7 @@ static int iwl_tx_skb(struct iwl_priv *priv, fc = le16_to_cpu(hdr->frame_control); -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); else if (ieee80211_is_assoc_request(fc)) @@ -2847,16 +2922,19 @@ static int iwl_tx_skb(struct iwl_priv *priv, IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif - if (!iwl_is_associated(priv) && + /* drop all data frame if we are not associated */ + if (!iwl4965_is_associated(priv) && !priv->assoc_id && ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { - IWL_DEBUG_DROP("Dropping - !iwl_is_associated\n"); + IWL_DEBUG_DROP("Dropping - !iwl4965_is_associated\n"); goto drop_unlock; } spin_unlock_irqrestore(&priv->lock, flags); hdr_len = ieee80211_get_hdrlen(fc); - sta_id = iwl_get_sta_id(priv, hdr); + + /* Find (or create) index into station table for destination station */ + sta_id = iwl4965_get_sta_id(priv, hdr); if (sta_id == IWL_INVALID_STATION) { DECLARE_MAC_BUF(mac); @@ -2876,40 +2954,62 @@ static int iwl_tx_skb(struct iwl_priv *priv, (hdr->seq_ctrl & __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); seq_number += 0x10; -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG /* aggregation is on for this */ if (ctl->flags & IEEE80211_TXCTL_HT_MPDU_AGG) txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ } + + /* Descriptor for chosen Tx queue */ txq = &priv->txq[txq_id]; q = &txq->q; spin_lock_irqsave(&priv->lock, flags); - tfd = &txq->bd[q->first_empty]; + /* Set up first empty TFD within this queue's circular TFD buffer */ + tfd = &txq->bd[q->write_ptr]; memset(tfd, 0, sizeof(*tfd)); control_flags = (u32 *) tfd; - idx = get_cmd_index(q, q->first_empty, 0); + idx = get_cmd_index(q, q->write_ptr, 0); - memset(&(txq->txb[q->first_empty]), 0, sizeof(struct iwl_tx_info)); - txq->txb[q->first_empty].skb[0] = skb; - memcpy(&(txq->txb[q->first_empty].status.control), + /* Set up driver data for this TFD */ + memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl4965_tx_info)); + txq->txb[q->write_ptr].skb[0] = skb; + memcpy(&(txq->txb[q->write_ptr].status.control), ctl, sizeof(struct ieee80211_tx_control)); + + /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = &txq->cmd[idx]; memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); memset(&out_cmd->cmd.tx, 0, sizeof(out_cmd->cmd.tx)); + + /* + * Set up the Tx-command (not MAC!) header. + * Store the chosen Tx queue and TFD index within the sequence field; + * after Tx, uCode's Tx response will return this value so driver can + * locate the frame within the tx queue and do post-tx processing. + */ out_cmd->hdr.cmd = REPLY_TX; out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->first_empty))); - /* copy frags header */ + INDEX_TO_SEQ(q->write_ptr))); + + /* Copy MAC header from skb into command buffer */ memcpy(out_cmd->cmd.tx.hdr, hdr, hdr_len); - /* hdr = (struct ieee80211_hdr *)out_cmd->cmd.tx.hdr; */ + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ len = priv->hw_setting.tx_cmd_len + - sizeof(struct iwl_cmd_header) + hdr_len; + sizeof(struct iwl4965_cmd_header) + hdr_len; len_org = len; len = (len + 3) & ~3; @@ -2919,33 +3019,40 @@ static int iwl_tx_skb(struct iwl_priv *priv, else len_org = 0; - txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx + - offsetof(struct iwl_cmd, hdr); + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl4965_cmd) * idx + + offsetof(struct iwl4965_cmd, hdr); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); + /* Add buffer containing Tx command and MAC(!) header to TFD's + * first entry */ + iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) - iwl_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); + iwl4965_build_tx_cmd_hwcrypto(priv, ctl, out_cmd, skb, 0); - /* 802.11 null functions have no payload... */ + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ len = skb->len - hdr_len; if (len) { phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); - iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); + iwl4965_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, len); } + /* Tell 4965 about any 2-byte padding after MAC header */ if (len_org) out_cmd->cmd.tx.tx_flags |= TX_CMD_FLG_MH_PAD_MSK; + /* Total # bytes to be transmitted */ len = (u16)skb->len; out_cmd->cmd.tx.len = cpu_to_le16(len); /* TODO need this for burst mode later on */ - iwl_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); + iwl4965_build_tx_cmd_basic(priv, out_cmd, ctl, hdr, unicast, sta_id); /* set is_hcca to 0; it probably will never be implemented */ - iwl_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); + iwl4965_hw_build_tx_cmd_rate(priv, out_cmd, ctl, hdr, sta_id, 0); iwl4965_tx_cmd(priv, out_cmd, sta_id, txcmd_phys, hdr, hdr_len, ctl, NULL); @@ -2961,27 +3068,29 @@ static int iwl_tx_skb(struct iwl_priv *priv, txq->need_update = 0; } - iwl_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, + iwl4965_print_hex_dump(IWL_DL_TX, out_cmd->cmd.payload, sizeof(out_cmd->cmd.tx)); - iwl_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, + iwl4965_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, ieee80211_get_hdrlen(fc)); + /* Set up entry for this TFD in Tx byte-count array */ iwl4965_tx_queue_update_wr_ptr(priv, txq, len); - q->first_empty = iwl_queue_inc_wrap(q->first_empty, q->n_bd); - rc = iwl_tx_queue_update_write_ptr(priv, txq); + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl4965_queue_inc_wrap(q->write_ptr, q->n_bd); + rc = iwl4965_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); if (rc) return rc; - if ((iwl_queue_space(q) < q->high_mark) + if ((iwl4965_queue_space(q) < q->high_mark) && priv->mac80211_registered) { if (wait_write_ptr) { spin_lock_irqsave(&priv->lock, flags); txq->need_update = 1; - iwl_tx_queue_update_write_ptr(priv, txq); + iwl4965_tx_queue_update_write_ptr(priv, txq); spin_unlock_irqrestore(&priv->lock, flags); } @@ -2996,13 +3105,13 @@ drop: return -1; } -static void iwl_set_rate(struct iwl_priv *priv) +static void iwl4965_set_rate(struct iwl4965_priv *priv) { const struct ieee80211_hw_mode *hw = NULL; struct ieee80211_rate *rate; int i; - hw = iwl_get_hw_mode(priv, priv->phymode); + hw = iwl4965_get_hw_mode(priv, priv->phymode); if (!hw) { IWL_ERROR("Failed to set rate: unable to get hw mode\n"); return; @@ -3020,7 +3129,7 @@ static void iwl_set_rate(struct iwl_priv *priv) if ((rate->val < IWL_RATE_COUNT) && (rate->flags & IEEE80211_RATE_SUPPORTED)) { IWL_DEBUG_RATE("Adding rate index %d (plcp %d)%s\n", - rate->val, iwl_rates[rate->val].plcp, + rate->val, iwl4965_rates[rate->val].plcp, (rate->flags & IEEE80211_RATE_BASIC) ? "*" : ""); priv->active_rate |= (1 << rate->val); @@ -3028,7 +3137,7 @@ static void iwl_set_rate(struct iwl_priv *priv) priv->active_rate_basic |= (1 << rate->val); } else IWL_DEBUG_RATE("Not adding rate %d (plcp %d)\n", - rate->val, iwl_rates[rate->val].plcp); + rate->val, iwl4965_rates[rate->val].plcp); } IWL_DEBUG_RATE("Set active_rate = %0x, active_rate_basic = %0x\n", @@ -3057,7 +3166,7 @@ static void iwl_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } -static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) +static void iwl4965_radio_kill_sw(struct iwl4965_priv *priv, int disable_radio) { unsigned long flags; @@ -3068,21 +3177,21 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) disable_radio ? "OFF" : "ON"); if (disable_radio) { - iwl_scan_cancel(priv); + iwl4965_scan_cancel(priv); /* FIXME: This is a workaround for AP */ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_SW_BIT_RFKILL); spin_unlock_irqrestore(&priv->lock, flags); - iwl_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); + iwl4965_send_card_state(priv, CARD_STATE_CMD_DISABLE, 0); set_bit(STATUS_RF_KILL_SW, &priv->status); } return; } spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); clear_bit(STATUS_RF_KILL_SW, &priv->status); spin_unlock_irqrestore(&priv->lock, flags); @@ -3091,9 +3200,9 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) msleep(10); spin_lock_irqsave(&priv->lock, flags); - iwl_read32(priv, CSR_UCODE_DRV_GP1); - if (!iwl_grab_restricted_access(priv)) - iwl_release_restricted_access(priv); + iwl4965_read32(priv, CSR_UCODE_DRV_GP1); + if (!iwl4965_grab_nic_access(priv)) + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { @@ -3106,7 +3215,7 @@ static void iwl_radio_kill_sw(struct iwl_priv *priv, int disable_radio) return; } -void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, +void iwl4965_set_decrypted_flag(struct iwl4965_priv *priv, struct sk_buff *skb, u32 decrypt_res, struct ieee80211_rx_status *stats) { u16 fc = @@ -3138,13 +3247,13 @@ void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, } } -void iwl_handle_data_packet_monitor(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, +void iwl4965_handle_data_packet_monitor(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb, void *data, short len, struct ieee80211_rx_status *stats, u16 phy_flags) { - struct iwl_rt_rx_hdr *iwl_rt; + struct iwl4965_rt_rx_hdr *iwl4965_rt; /* First cache any information we need before we overwrite * the information provided in the skb from the hardware */ @@ -3155,26 +3264,26 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, __le16 phy_flags_hw = cpu_to_le16(phy_flags); /* We received data from the HW, so stop the watchdog */ - if (len > IWL_RX_BUF_SIZE - sizeof(*iwl_rt)) { + if (len > priv->hw_setting.rx_buf_size - sizeof(*iwl4965_rt)) { IWL_DEBUG_DROP("Dropping too large packet in monitor\n"); return; } /* copy the frame data to write after where the radiotap header goes */ - iwl_rt = (void *)rxb->skb->data; - memmove(iwl_rt->payload, data, len); + iwl4965_rt = (void *)rxb->skb->data; + memmove(iwl4965_rt->payload, data, len); - iwl_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; - iwl_rt->rt_hdr.it_pad = 0; /* always good to zero */ + iwl4965_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; + iwl4965_rt->rt_hdr.it_pad = 0; /* always good to zero */ /* total header + data */ - iwl_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl_rt)); + iwl4965_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*iwl4965_rt)); /* Set the size of the skb to the size of the frame */ - skb_put(rxb->skb, sizeof(*iwl_rt) + len); + skb_put(rxb->skb, sizeof(*iwl4965_rt) + len); /* Big bitfield of all the fields we provide in radiotap */ - iwl_rt->rt_hdr.it_present = + iwl4965_rt->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) | (1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | @@ -3184,39 +3293,39 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, (1 << IEEE80211_RADIOTAP_ANTENNA)); /* Zero the flags, we'll add to them as we go */ - iwl_rt->rt_flags = 0; + iwl4965_rt->rt_flags = 0; - iwl_rt->rt_tsf = cpu_to_le64(tsf); + iwl4965_rt->rt_tsf = cpu_to_le64(tsf); /* Convert to dBm */ - iwl_rt->rt_dbmsignal = signal; - iwl_rt->rt_dbmnoise = noise; + iwl4965_rt->rt_dbmsignal = signal; + iwl4965_rt->rt_dbmnoise = noise; /* Convert the channel frequency and set the flags */ - iwl_rt->rt_channelMHz = cpu_to_le16(stats->freq); + iwl4965_rt->rt_channelMHz = cpu_to_le16(stats->freq); if (!(phy_flags_hw & RX_RES_PHY_FLAGS_BAND_24_MSK)) - iwl_rt->rt_chbitmask = + iwl4965_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ)); else if (phy_flags_hw & RX_RES_PHY_FLAGS_MOD_CCK_MSK) - iwl_rt->rt_chbitmask = + iwl4965_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ)); else /* 802.11g */ - iwl_rt->rt_chbitmask = + iwl4965_rt->rt_chbitmask = cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ)); - rate = iwl_rate_index_from_plcp(rate); + rate = iwl4965_rate_index_from_plcp(rate); if (rate == -1) - iwl_rt->rt_rate = 0; + iwl4965_rt->rt_rate = 0; else - iwl_rt->rt_rate = iwl_rates[rate].ieee; + iwl4965_rt->rt_rate = iwl4965_rates[rate].ieee; /* antenna number */ - iwl_rt->rt_antenna = + iwl4965_rt->rt_antenna = le16_to_cpu(phy_flags_hw & RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; /* set the preamble flag if we have it */ if (phy_flags_hw & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) - iwl_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; + iwl4965_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; IWL_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len); @@ -3228,7 +3337,7 @@ void iwl_handle_data_packet_monitor(struct iwl_priv *priv, #define IWL_PACKET_RETRY_TIME HZ -int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) +int iwl4965_is_duplicate_packet(struct iwl4965_priv *priv, struct ieee80211_hdr *header) { u16 sc = le16_to_cpu(header->seq_ctrl); u16 seq = (sc & IEEE80211_SCTL_SEQ) >> 4; @@ -3239,29 +3348,26 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) switch (priv->iw_mode) { case IEEE80211_IF_TYPE_IBSS:{ struct list_head *p; - struct iwl_ibss_seq *entry = NULL; + struct iwl4965_ibss_seq *entry = NULL; u8 *mac = header->addr2; int index = mac[5] & (IWL_IBSS_MAC_HASH_SIZE - 1); __list_for_each(p, &priv->ibss_mac_hash[index]) { - entry = - list_entry(p, struct iwl_ibss_seq, list); + entry = list_entry(p, struct iwl4965_ibss_seq, list); if (!compare_ether_addr(entry->mac, mac)) break; } if (p == &priv->ibss_mac_hash[index]) { entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) { - IWL_ERROR - ("Cannot malloc new mac entry\n"); + IWL_ERROR("Cannot malloc new mac entry\n"); return 0; } memcpy(entry->mac, mac, ETH_ALEN); entry->seq_num = seq; entry->frag_num = frag; entry->packet_time = jiffies; - list_add(&entry->list, - &priv->ibss_mac_hash[index]); + list_add(&entry->list, &priv->ibss_mac_hash[index]); return 0; } last_seq = &entry->seq_num; @@ -3295,7 +3401,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) return 1; } -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT #include "iwl-spectrum.h" @@ -3310,7 +3416,7 @@ int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) * the lower 3 bytes is the time in usec within one beacon interval */ -static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval) +static u32 iwl4965_usecs_to_beacons(u32 usec, u32 beacon_interval) { u32 quot; u32 rem; @@ -3329,7 +3435,7 @@ static u32 iwl_usecs_to_beacons(u32 usec, u32 beacon_interval) * the same as HW timer counter counting down */ -static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) +static __le32 iwl4965_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) { u32 base_low = base & BEACON_TIME_MASK_LOW; u32 addon_low = addon & BEACON_TIME_MASK_LOW; @@ -3348,13 +3454,13 @@ static __le32 iwl_add_beacon_time(u32 base, u32 addon, u32 beacon_interval) return cpu_to_le32(res); } -static int iwl_get_measurement(struct iwl_priv *priv, +static int iwl4965_get_measurement(struct iwl4965_priv *priv, struct ieee80211_measurement_params *params, u8 type) { - struct iwl_spectrum_cmd spectrum; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { + struct iwl4965_spectrum_cmd spectrum; + struct iwl4965_rx_packet *res; + struct iwl4965_host_cmd cmd = { .id = REPLY_SPECTRUM_MEASUREMENT_CMD, .data = (void *)&spectrum, .meta.flags = CMD_WANT_SKB, @@ -3364,9 +3470,9 @@ static int iwl_get_measurement(struct iwl_priv *priv, int spectrum_resp_status; int duration = le16_to_cpu(params->duration); - if (iwl_is_associated(priv)) + if (iwl4965_is_associated(priv)) add_time = - iwl_usecs_to_beacons( + iwl4965_usecs_to_beacons( le64_to_cpu(params->start_time) - priv->last_tsf, le16_to_cpu(priv->rxon_timing.beacon_interval)); @@ -3379,9 +3485,9 @@ static int iwl_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 (iwl4965_is_associated(priv)) spectrum.start_time = - iwl_add_beacon_time(priv->last_beacon_time, + iwl4965_add_beacon_time(priv->last_beacon_time, add_time, le16_to_cpu(priv->rxon_timing.beacon_interval)); else @@ -3394,11 +3500,11 @@ static int iwl_get_measurement(struct iwl_priv *priv, spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl4965_send_cmd_sync(priv, &cmd); if (rc) return rc; - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + res = (struct iwl4965_rx_packet *)cmd.meta.u.skb->data; if (res->hdr.flags & IWL_CMD_FAILED_MSK) { IWL_ERROR("Bad return from REPLY_RX_ON_ASSOC command\n"); rc = -EIO; @@ -3428,8 +3534,8 @@ static int iwl_get_measurement(struct iwl_priv *priv, } #endif -static void iwl_txstatus_to_ieee(struct iwl_priv *priv, - struct iwl_tx_info *tx_sta) +static void iwl4965_txstatus_to_ieee(struct iwl4965_priv *priv, + struct iwl4965_tx_info *tx_sta) { tx_sta->status.ack_signal = 0; @@ -3448,41 +3554,41 @@ static void iwl_txstatus_to_ieee(struct iwl_priv *priv, } /** - * iwl_tx_queue_reclaim - Reclaim Tx queue entries no more used by NIC. + * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd * - * When FW advances 'R' index, all entries between old and - * new 'R' index need to be reclaimed. As result, some free space - * forms. If there is enough free space (> low mark), wake Tx queue. + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. */ -int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) +int iwl4965_tx_queue_reclaim(struct iwl4965_priv *priv, int txq_id, int index) { - struct iwl_tx_queue *txq = &priv->txq[txq_id]; - struct iwl_queue *q = &txq->q; + struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; + struct iwl4965_queue *q = &txq->q; int nfreed = 0; if ((index >= q->n_bd) || (x2_queue_used(q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " "is out of range [0-%d] %d %d.\n", txq_id, - index, q->n_bd, q->first_empty, q->last_used); + index, q->n_bd, q->write_ptr, q->read_ptr); return 0; } - for (index = iwl_queue_inc_wrap(index, q->n_bd); - q->last_used != index; - q->last_used = iwl_queue_inc_wrap(q->last_used, q->n_bd)) { + for (index = iwl4965_queue_inc_wrap(index, q->n_bd); + q->read_ptr != index; + q->read_ptr = iwl4965_queue_inc_wrap(q->read_ptr, q->n_bd)) { if (txq_id != IWL_CMD_QUEUE_NUM) { - iwl_txstatus_to_ieee(priv, - &(txq->txb[txq->q.last_used])); - iwl_hw_txq_free_tfd(priv, txq); + iwl4965_txstatus_to_ieee(priv, + &(txq->txb[txq->q.read_ptr])); + iwl4965_hw_txq_free_tfd(priv, txq); } else if (nfreed > 1) { IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, - q->first_empty, q->last_used); + q->write_ptr, q->read_ptr); queue_work(priv->workqueue, &priv->restart); } nfreed++; } - if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && + if (iwl4965_queue_space(q) > q->low_mark && (txq_id >= 0) && (txq_id != IWL_CMD_QUEUE_NUM) && priv->mac80211_registered) ieee80211_wake_queue(priv->hw, txq_id); @@ -3491,7 +3597,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) return nfreed; } -static int iwl_is_tx_success(u32 status) +static int iwl4965_is_tx_success(u32 status) { status &= TX_STATUS_MSK; return (status == TX_STATUS_SUCCESS) @@ -3503,22 +3609,22 @@ static int iwl_is_tx_success(u32 status) * Generic RX handler implementations * ******************************************************************************/ -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG -static inline int iwl_get_ra_sta_id(struct iwl_priv *priv, +static inline int iwl4965_get_ra_sta_id(struct iwl4965_priv *priv, struct ieee80211_hdr *hdr) { if (priv->iw_mode == IEEE80211_IF_TYPE_STA) return IWL_AP_ID; else { u8 *da = ieee80211_get_DA(hdr); - return iwl_hw_find_station(priv, da); + return iwl4965_hw_find_station(priv, da); } } -static struct ieee80211_hdr *iwl_tx_queue_get_hdr( - struct iwl_priv *priv, int txq_id, int idx) +static struct ieee80211_hdr *iwl4965_tx_queue_get_hdr( + struct iwl4965_priv *priv, int txq_id, int idx) { if (priv->txq[txq_id].txb[idx].skb[0]) return (struct ieee80211_hdr *)priv->txq[txq_id]. @@ -3526,16 +3632,20 @@ static struct ieee80211_hdr *iwl_tx_queue_get_hdr( return NULL; } -static inline u32 iwl_get_scd_ssn(struct iwl_tx_resp *tx_resp) +static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) { __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + tx_resp->frame_count); return le32_to_cpu(*scd_ssn) & MAX_SN; } -static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, - struct iwl_ht_agg *agg, - struct iwl_tx_resp *tx_resp, + +/** + * iwl4965_tx_status_reply_tx - Handle Tx rspnse for frames in aggregation queue + */ +static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, + struct iwl4965_ht_agg *agg, + struct iwl4965_tx_resp *tx_resp, u16 start_idx) { u32 status; @@ -3547,15 +3657,17 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, u16 seq; if (agg->wait_for_ba) - IWL_DEBUG_TX_REPLY("got tx repsons w/o back\n"); + IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); agg->frame_count = tx_resp->frame_count; agg->start_idx = start_idx; agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); agg->bitmap0 = agg->bitmap1 = 0; + /* # frames attempted by Tx command */ if (agg->frame_count == 1) { - struct iwl_tx_queue *txq ; + /* Only one frame was attempted; no block-ack will arrive */ + struct iwl4965_tx_queue *txq ; status = le32_to_cpu(frame_status[0]); txq_id = agg->txq_id; @@ -3564,28 +3676,30 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d \n", agg->frame_count, agg->start_idx); - tx_status = &(priv->txq[txq_id].txb[txq->q.last_used].status); + tx_status = &(priv->txq[txq_id].txb[txq->q.read_ptr].status); tx_status->retry_count = tx_resp->failure_frame; tx_status->queue_number = status & 0xff; tx_status->queue_length = tx_resp->bt_kill_count; tx_status->queue_length |= tx_resp->failure_rts; - tx_status->flags = iwl_is_tx_success(status)? + tx_status->flags = iwl4965_is_tx_success(status)? IEEE80211_TX_STATUS_ACK : 0; tx_status->control.tx_rate = - iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags); + iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); /* FIXME: code repetition end */ IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, tx_resp->failure_frame); IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", - iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags)); + iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); agg->wait_for_ba = 0; } else { + /* Two or more frames were attempted; expect block-ack */ u64 bitmap = 0; int start = agg->start_idx; + /* Construct bit-map of pending frames within Tx window */ for (i = 0; i < agg->frame_count; i++) { u16 sc; status = le32_to_cpu(frame_status[i]); @@ -3600,7 +3714,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n", agg->frame_count, txq_id, idx); - hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); + hdr = iwl4965_tx_queue_get_hdr(priv, txq_id, idx); sc = le16_to_cpu(hdr->seq_ctrl); if (idx != (SEQ_TO_SN(sc) & 0xff)) { @@ -3649,19 +3763,22 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, #endif #endif -static void iwl_rx_reply_tx(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +/** + * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response + */ +static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); - struct iwl_tx_queue *txq = &priv->txq[txq_id]; + struct iwl4965_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_status *tx_status; - struct iwl_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le32_to_cpu(tx_resp->status); -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG int tid, sta_id; #endif #endif @@ -3669,18 +3786,18 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv, if ((index >= txq->q.n_bd) || (x2_queue_used(&txq->q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " "is out of range [0-%d] %d %d\n", txq_id, - index, txq->q.n_bd, txq->q.first_empty, - txq->q.last_used); + index, txq->q.n_bd, txq->q.write_ptr, + txq->q.read_ptr); return; } -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG if (txq->sched_retry) { - const u32 scd_ssn = iwl_get_scd_ssn(tx_resp); + const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); struct ieee80211_hdr *hdr = - iwl_tx_queue_get_hdr(priv, txq_id, index); - struct iwl_ht_agg *agg = NULL; + iwl4965_tx_queue_get_hdr(priv, txq_id, index); + struct iwl4965_ht_agg *agg = NULL; __le16 *qc = ieee80211_get_qos_ctrl(hdr); if (qc == NULL) { @@ -3690,7 +3807,7 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv, tid = le16_to_cpu(*qc) & 0xf; - sta_id = iwl_get_ra_sta_id(priv, hdr); + sta_id = iwl4965_get_ra_sta_id(priv, hdr); if (unlikely(sta_id == IWL_INVALID_STATION)) { IWL_ERROR("Station not known for\n"); return; @@ -3701,20 +3818,20 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv, iwl4965_tx_status_reply_tx(priv, agg, tx_resp, index); if ((tx_resp->frame_count == 1) && - !iwl_is_tx_success(status)) { + !iwl4965_is_tx_success(status)) { /* TODO: send BAR */ } - if ((txq->q.last_used != (scd_ssn & 0xff))) { - index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); + if ((txq->q.read_ptr != (scd_ssn & 0xff))) { + index = iwl4965_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " "%d index %d\n", scd_ssn , index); - iwl_tx_queue_reclaim(priv, txq_id, index); + iwl4965_tx_queue_reclaim(priv, txq_id, index); } } else { -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ - tx_status = &(txq->txb[txq->q.last_used].status); +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ + tx_status = &(txq->txb[txq->q.read_ptr].status); tx_status->retry_count = tx_resp->failure_frame; tx_status->queue_number = status; @@ -3722,35 +3839,35 @@ static void iwl_rx_reply_tx(struct iwl_priv *priv, tx_status->queue_length |= tx_resp->failure_rts; tx_status->flags = - iwl_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; + iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; tx_status->control.tx_rate = - iwl_hw_get_rate_n_flags(tx_resp->rate_n_flags); + iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " - "retries %d\n", txq_id, iwl_get_tx_fail_reason(status), + "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), status, le32_to_cpu(tx_resp->rate_n_flags), tx_resp->failure_frame); IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); if (index != -1) - iwl_tx_queue_reclaim(priv, txq_id, index); -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG + iwl4965_tx_queue_reclaim(priv, txq_id, index); +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG } -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); } -static void iwl_rx_reply_alive(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_alive(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_alive_resp *palive; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_alive_resp *palive; struct delayed_work *pwork; palive = &pkt->u.alive_frame; @@ -3764,12 +3881,12 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, IWL_DEBUG_INFO("Initialization Alive received.\n"); memcpy(&priv->card_alive_init, &pkt->u.alive_frame, - sizeof(struct iwl_init_alive_resp)); + sizeof(struct iwl4965_init_alive_resp)); pwork = &priv->init_alive_start; } else { IWL_DEBUG_INFO("Runtime Alive received.\n"); memcpy(&priv->card_alive, &pkt->u.alive_frame, - sizeof(struct iwl_alive_resp)); + sizeof(struct iwl4965_alive_resp)); pwork = &priv->alive_start; } @@ -3782,19 +3899,19 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv, IWL_WARNING("uCode did not respond OK.\n"); } -static void iwl_rx_reply_add_sta(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_add_sta(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RX("Received REPLY_ADD_STA: 0x%02X\n", pkt->u.status); return; } -static void iwl_rx_reply_error(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_error(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; IWL_ERROR("Error Reply type 0x%08X cmd %s (0x%02X) " "seq 0x%04X ser 0x%08X\n", @@ -3807,23 +3924,23 @@ static void iwl_rx_reply_error(struct iwl_priv *priv, #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x -static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_csa(struct iwl4965_priv *priv, struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; - struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rxon_cmd *rxon = (void *)&priv->active_rxon; + struct iwl4965_csa_notification *csa = &(pkt->u.csa_notif); IWL_DEBUG_11H("CSA notif: channel %d, status %d\n", le16_to_cpu(csa->channel), le32_to_cpu(csa->status)); rxon->channel = csa->channel; priv->staging_rxon.channel = csa->channel; } -static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_spectrum_measure_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif); +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif); if (!report->state) { IWL_DEBUG(IWL_DL_11H | IWL_DL_INFO, @@ -3836,31 +3953,31 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, #endif } -static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_pm_sleep_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif); +#ifdef CONFIG_IWL4965_DEBUG + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_sleep_notification *sleep = &(pkt->u.sleep_notif); IWL_DEBUG_RX("sleep mode: %d, src: %d\n", sleep->pm_sleep_mode, sleep->pm_wakeup_src); #endif } -static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_pm_debug_statistics_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; IWL_DEBUG_RADIO("Dumping %d bytes of unhandled " "notification for %s:\n", le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); - iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); + iwl4965_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); } -static void iwl_bg_beacon_update(struct work_struct *work) +static void iwl4965_bg_beacon_update(struct work_struct *work) { - struct iwl_priv *priv = - container_of(work, struct iwl_priv, beacon_update); + struct iwl4965_priv *priv = + container_of(work, struct iwl4965_priv, beacon_update); struct sk_buff *beacon; /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ @@ -3879,16 +3996,16 @@ static void iwl_bg_beacon_update(struct work_struct *work) priv->ibss_beacon = beacon; mutex_unlock(&priv->mutex); - iwl_send_beacon_cmd(priv); + iwl4965_send_beacon_cmd(priv); } -static void iwl_rx_beacon_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_beacon_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_beacon_notif *beacon = &(pkt->u.beacon_status); - u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); +#ifdef CONFIG_IWL4965_DEBUG + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); + u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); IWL_DEBUG_RX("beacon status %x retries %d iss %d " "tsf %d %d rate %d\n", @@ -3905,25 +4022,25 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, } /* Service response to REPLY_SCAN_CMD (0x80) */ -static void iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_reply_scan(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanreq_notification *notif = - (struct iwl_scanreq_notification *)pkt->u.raw; +#ifdef CONFIG_IWL4965_DEBUG + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_scanreq_notification *notif = + (struct iwl4965_scanreq_notification *)pkt->u.raw; IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); #endif } /* Service SCAN_START_NOTIFICATION (0x82) */ -static void iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_scan_start_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanstart_notification *notif = - (struct iwl_scanstart_notification *)pkt->u.raw; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_scanstart_notification *notif = + (struct iwl4965_scanstart_notification *)pkt->u.raw; priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); IWL_DEBUG_SCAN("Scan start: " "%d [802.11%s] " @@ -3935,12 +4052,12 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv, } /* Service SCAN_RESULTS_NOTIFICATION (0x83) */ -static void iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_scan_results_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scanresults_notification *notif = - (struct iwl_scanresults_notification *)pkt->u.raw; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_scanresults_notification *notif = + (struct iwl4965_scanresults_notification *)pkt->u.raw; IWL_DEBUG_SCAN("Scan ch.res: " "%d [802.11%s] " @@ -3956,14 +4073,15 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, (priv->last_scan_jiffies, jiffies))); priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; } /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ -static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_scan_complete_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; - struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", scan_notif->scanned_channels, @@ -3998,6 +4116,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, } priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; IWL_DEBUG_INFO("Setting scan to off\n"); clear_bit(STATUS_SCANNING, &priv->status); @@ -4016,10 +4135,10 @@ reschedule: /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ -static void iwl_rx_card_state_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_rx_card_state_notif(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (void *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (void *)rxb->skb->data; u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); unsigned long status = priv->status; @@ -4030,35 +4149,35 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | RF_CARD_DISABLED)) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted( + if (!iwl4965_grab_nic_access(priv)) { + iwl4965_write_direct32( priv, HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } if (!(flags & RXON_CARD_DISABLED)) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted( + if (!iwl4965_grab_nic_access(priv)) { + iwl4965_write_direct32( priv, HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } } if (flags & RF_CARD_DISABLED) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - iwl_read32(priv, CSR_UCODE_DRV_GP1); - if (!iwl_grab_restricted_access(priv)) - iwl_release_restricted_access(priv); + iwl4965_read32(priv, CSR_UCODE_DRV_GP1); + if (!iwl4965_grab_nic_access(priv)) + iwl4965_release_nic_access(priv); } } @@ -4074,7 +4193,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_SW, &priv->status); if (!(flags & RXON_CARD_DISABLED)) - iwl_scan_cancel(priv); + iwl4965_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) || @@ -4086,7 +4205,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, } /** - * iwl_setup_rx_handlers - Initialize Rx handler callbacks + * iwl4965_setup_rx_handlers - Initialize Rx handler callbacks * * Setup the RX handlers for each of the reply types sent from the uCode * to the host. @@ -4094,61 +4213,58 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, * This function chains into the hardware specific files for them to setup * any hardware specific handlers as well. */ -static void iwl_setup_rx_handlers(struct iwl_priv *priv) +static void iwl4965_setup_rx_handlers(struct iwl4965_priv *priv) { - priv->rx_handlers[REPLY_ALIVE] = iwl_rx_reply_alive; - priv->rx_handlers[REPLY_ADD_STA] = iwl_rx_reply_add_sta; - priv->rx_handlers[REPLY_ERROR] = iwl_rx_reply_error; - priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa; + priv->rx_handlers[REPLY_ALIVE] = iwl4965_rx_reply_alive; + priv->rx_handlers[REPLY_ADD_STA] = iwl4965_rx_reply_add_sta; + priv->rx_handlers[REPLY_ERROR] = iwl4965_rx_reply_error; + priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl4965_rx_csa; priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] = - iwl_rx_spectrum_measure_notif; - priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl_rx_pm_sleep_notif; + iwl4965_rx_spectrum_measure_notif; + priv->rx_handlers[PM_SLEEP_NOTIFICATION] = iwl4965_rx_pm_sleep_notif; priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] = - iwl_rx_pm_debug_statistics_notif; - priv->rx_handlers[BEACON_NOTIFICATION] = iwl_rx_beacon_notif; - - /* NOTE: iwl_rx_statistics is different based on whether - * the build is for the 3945 or the 4965. See the - * corresponding implementation in iwl-XXXX.c - * - * The same handler is used for both the REPLY to a - * discrete statistics request from the host as well as - * for the periodic statistics notification from the uCode + iwl4965_rx_pm_debug_statistics_notif; + priv->rx_handlers[BEACON_NOTIFICATION] = iwl4965_rx_beacon_notif; + + /* + * The same handler is used for both the REPLY to a discrete + * statistics request from the host as well as for the periodic + * statistics notifications (after received beacons) from the uCode. */ - priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl_hw_rx_statistics; - priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl_hw_rx_statistics; + priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; + priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; - priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan; - priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif; + priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan; + priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif; priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = - iwl_rx_scan_results_notif; + iwl4965_rx_scan_results_notif; priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = - iwl_rx_scan_complete_notif; - priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl_rx_card_state_notif; - priv->rx_handlers[REPLY_TX] = iwl_rx_reply_tx; + iwl4965_rx_scan_complete_notif; + priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; + priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; - /* Setup hardware specific Rx handlers */ - iwl_hw_rx_handler_setup(priv); + /* Set up hardware specific Rx handlers */ + iwl4965_hw_rx_handler_setup(priv); } /** - * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them + * iwl4965_tx_cmd_complete - Pull unused buffers off the queue and reclaim them * @rxb: Rx buffer to reclaim * * If an Rx buffer has an async callback associated with it the callback * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -static void iwl_tx_cmd_complete(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) +static void iwl4965_tx_cmd_complete(struct iwl4965_priv *priv, + struct iwl4965_rx_mem_buffer *rxb) { - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_rx_packet *pkt = (struct iwl4965_rx_packet *)rxb->skb->data; u16 sequence = le16_to_cpu(pkt->hdr.sequence); int txq_id = SEQ_TO_QUEUE(sequence); int index = SEQ_TO_INDEX(sequence); int huge = sequence & SEQ_HUGE_FRAME; int cmd_index; - struct iwl_cmd *cmd; + struct iwl4965_cmd *cmd; /* 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 @@ -4169,7 +4285,7 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, !cmd->meta.u.callback(priv, cmd, rxb->skb)) rxb->skb = NULL; - iwl_tx_queue_reclaim(priv, txq_id, index); + iwl4965_tx_queue_reclaim(priv, txq_id, index); if (!(cmd->meta.flags & CMD_ASYNC)) { clear_bit(STATUS_HCMD_ACTIVE, &priv->status); @@ -4181,9 +4297,11 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, /* * Rx theory of operation * - * The host allocates 32 DMA target addresses and passes the host address - * to the firmware at register IWL_RFDS_TABLE_LOWER + N * RFD_SIZE where N is - * 0 to 31 + * Driver allocates a circular buffer of Receive Buffer Descriptors (RBDs), + * each of which point to Receive Buffers to be filled by 4965. These get + * used not only for Rx frames, but for any command response or notification + * from the 4965. The driver and 4965 manage the Rx buffers by means + * of indexes into the circular buffer. * * Rx Queue Indexes * The host/firmware share two index registers for managing the Rx buffers. @@ -4199,10 +4317,10 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * The queue is empty (no good data) if WRITE = READ - 1, and is full if * WRITE = READ. * - * During initialization the host sets up the READ queue position to the first + * During initialization, the host sets up the READ queue position to the first * INDEX position, and WRITE to the last (READ - 1 wrapped) * - * When the firmware places a packet in a buffer it will advance the READ index + * When the firmware places a packet in a buffer, it will advance the READ index * and fire the RX interrupt. The driver can then query the READ index and * process as many packets as possible, moving the WRITE index forward as it * resets the Rx queue buffers with new memory. @@ -4210,8 +4328,8 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * The management in the driver is as follows: * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled - * to replensish the iwl->rxq->rx_free. - * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the + * to replenish the iwl->rxq->rx_free. + * + In iwl4965_rx_replenish (scheduled) if 'processed' != 'read' then the * iwl->rxq is replenished and the READ INDEX is updated (updating the * 'processed' and 'read' driver indexes as well) * + A received packet is processed and handed to the kernel network stack, @@ -4224,28 +4342,28 @@ static void iwl_tx_cmd_complete(struct iwl_priv *priv, * * Driver sequence: * - * iwl_rx_queue_alloc() Allocates rx_free - * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl_rx_queue_restock - * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx + * iwl4965_rx_queue_alloc() Allocates rx_free + * iwl4965_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl4965_rx_queue_restock + * iwl4965_rx_queue_restock() Moves available buffers from rx_free into Rx * queue, updates firmware pointers, and updates * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl_rx_replenish + * are available, schedules iwl4965_rx_replenish * * -- enable interrupts -- - * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the + * ISR - iwl4965_rx() Detach iwl4965_rx_mem_buffers from pool up to the * READ INDEX, detaching the SKB from the pool. * Moves the packet buffer from queue to rx_used. - * Calls iwl_rx_queue_restock to refill any empty + * Calls iwl4965_rx_queue_restock to refill any empty * slots. * ... * */ /** - * iwl_rx_queue_space - Return number of free slots available in queue. + * iwl4965_rx_queue_space - Return number of free slots available in queue. */ -static int iwl_rx_queue_space(const struct iwl_rx_queue *q) +static int iwl4965_rx_queue_space(const struct iwl4965_rx_queue *q) { int s = q->read - q->write; if (s <= 0) @@ -4258,15 +4376,9 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q) } /** - * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue - * - * NOTE: This function has 3945 and 4965 specific code sections - * but is declared in base due to the majority of the - * implementation being the same (only a numeric constant is - * different) - * + * iwl4965_rx_queue_update_write_ptr - Update the write pointer for the RX queue */ -int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) +int iwl4965_rx_queue_update_write_ptr(struct iwl4965_priv *priv, struct iwl4965_rx_queue *q) { u32 reg = 0; int rc = 0; @@ -4277,24 +4389,29 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) if (q->need_update == 0) goto exit_unlock; + /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &priv->status)) { - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { - iwl_set_bit(priv, CSR_GP_CNTRL, + iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); goto exit_unlock; } - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) goto exit_unlock; - iwl_write_restricted(priv, FH_RSCSR_CHNL0_WPTR, + /* Device expects a multiple of 8 */ + iwl4965_write_direct32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); + + /* Else device is assumed to be awake */ } else - iwl_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); + /* Device expects a multiple of 8 */ + iwl4965_write32(priv, FH_RSCSR_CHNL0_WPTR, q->write & ~0x7); q->need_update = 0; @@ -4305,11 +4422,9 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q) } /** - * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer pointer. - * - * NOTE: This function has 3945 and 4965 specific code paths in it. + * iwl4965_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr */ -static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, +static inline __le32 iwl4965_dma_addr2rbd_ptr(struct iwl4965_priv *priv, dma_addr_t dma_addr) { return cpu_to_le32((u32)(dma_addr >> 8)); @@ -4317,31 +4432,34 @@ static inline __le32 iwl_dma_addr2rbd_ptr(struct iwl_priv *priv, /** - * iwl_rx_queue_restock - refill RX queue from pre-allocated pool + * iwl4965_rx_queue_restock - refill RX queue from pre-allocated pool * - * If there are slots in the RX queue that need to be restocked, + * If there are slots in the RX queue that need to be restocked, * and we have free pre-allocated buffers, fill the ranks as much - * as we can pulling from rx_free. + * as we can, pulling from rx_free. * * This moves the 'write' index forward to catch up with 'processed', and * also updates the memory address in the firmware to reference the new * target buffer. */ -int iwl_rx_queue_restock(struct iwl_priv *priv) +static int iwl4965_rx_queue_restock(struct iwl4965_priv *priv) { - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl4965_rx_queue *rxq = &priv->rxq; struct list_head *element; - struct iwl_rx_mem_buffer *rxb; + struct iwl4965_rx_mem_buffer *rxb; unsigned long flags; int write, rc; spin_lock_irqsave(&rxq->lock, flags); write = rxq->write & ~0x7; - while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + while ((iwl4965_rx_queue_space(rxq) > 0) && (rxq->free_count)) { + /* Get next free Rx buffer, remove from free list */ element = rxq->rx_free.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); list_del(element); - rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(priv, rxb->dma_addr); + + /* Point to Rx buffer via next RBD in circular buffer */ + rxq->bd[rxq->write] = iwl4965_dma_addr2rbd_ptr(priv, rxb->dma_addr); rxq->queue[rxq->write] = rxb; rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; rxq->free_count--; @@ -4353,13 +4471,14 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->rx_replenish); - /* If we've added more space for the firmware to place data, tell it */ + /* If we've added more space for the firmware to place data, tell it. + * Increment device's write pointer in multiples of 8. */ if ((write != (rxq->write & ~0x7)) || (abs(rxq->write - rxq->read) > 7)) { spin_lock_irqsave(&rxq->lock, flags); rxq->need_update = 1; spin_unlock_irqrestore(&rxq->lock, flags); - rc = iwl_rx_queue_update_write_ptr(priv, rxq); + rc = iwl4965_rx_queue_update_write_ptr(priv, rxq); if (rc) return rc; } @@ -4368,26 +4487,28 @@ int iwl_rx_queue_restock(struct iwl_priv *priv) } /** - * iwl_rx_replensih - Move all used packet from rx_used to rx_free + * iwl4965_rx_replenish - Move all used packet from rx_used to rx_free * * When moving to rx_free an SKB is allocated for the slot. * - * Also restock the Rx queue via iwl_rx_queue_restock. - * This is called as a scheduled work item (except for during intialization) + * Also restock the Rx queue via iwl4965_rx_queue_restock. + * This is called as a scheduled work item (except for during initialization) */ -void iwl_rx_replenish(void *data) +static void iwl4965_rx_allocate(struct iwl4965_priv *priv) { - struct iwl_priv *priv = data; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl4965_rx_queue *rxq = &priv->rxq; struct list_head *element; - struct iwl_rx_mem_buffer *rxb; + struct iwl4965_rx_mem_buffer *rxb; unsigned long flags; spin_lock_irqsave(&rxq->lock, flags); while (!list_empty(&rxq->rx_used)) { element = rxq->rx_used.next; - rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + rxb = list_entry(element, struct iwl4965_rx_mem_buffer, list); + + /* Alloc a new receive buffer */ rxb->skb = - alloc_skb(IWL_RX_BUF_SIZE, __GFP_NOWARN | GFP_ATOMIC); + alloc_skb(priv->hw_setting.rx_buf_size, + __GFP_NOWARN | GFP_ATOMIC); if (!rxb->skb) { if (net_ratelimit()) printk(KERN_CRIT DRV_NAME @@ -4399,32 +4520,55 @@ void iwl_rx_replenish(void *data) } priv->alloc_rxb_skb++; list_del(element); + + /* Get physical address of RB/SKB */ rxb->dma_addr = pci_map_single(priv->pci_dev, rxb->skb->data, - IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + priv->hw_setting.rx_buf_size, PCI_DMA_FROMDEVICE); list_add_tail(&rxb->list, &rxq->rx_free); rxq->free_count++; } spin_unlock_irqrestore(&rxq->lock, flags); +} + +/* + * this should be called while priv->lock is locked +*/ +void __iwl4965_rx_replenish(void *data) +{ + struct iwl4965_priv *priv = data; + + iwl4965_rx_allocate(priv); + iwl4965_rx_queue_restock(priv); +} + + +void iwl4965_rx_replenish(void *data) +{ + struct iwl4965_priv *priv = data; + unsigned long flags; + + iwl4965_rx_allocate(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_rx_queue_restock(priv); + iwl4965_rx_queue_restock(priv); spin_unlock_irqrestore(&priv->lock, flags); } /* Assumes that the skb field of the buffers in 'pool' is kept accurate. - * If an SKB has been detached, the POOL needs to have it's SKB set to NULL + * If an SKB has been detached, the POOL needs to have its SKB set to NULL * This free routine walks the list of POOL entries and if SKB is set to * non NULL it is unmapped and freed */ -void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +static void iwl4965_rx_queue_free(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq) { int i; for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) { if (rxq->pool[i].skb != NULL) { pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, - IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + priv->hw_setting.rx_buf_size, + PCI_DMA_FROMDEVICE); dev_kfree_skb(rxq->pool[i].skb); } } @@ -4434,21 +4578,25 @@ void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq) rxq->bd = NULL; } -int iwl_rx_queue_alloc(struct iwl_priv *priv) +int iwl4965_rx_queue_alloc(struct iwl4965_priv *priv) { - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl4965_rx_queue *rxq = &priv->rxq; struct pci_dev *dev = priv->pci_dev; int i; spin_lock_init(&rxq->lock); INIT_LIST_HEAD(&rxq->rx_free); INIT_LIST_HEAD(&rxq->rx_used); + + /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */ rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr); if (!rxq->bd) return -ENOMEM; + /* Fill the rx_used queue with _all_ of the Rx buffers */ for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + /* Set us so that we have processed and used all buffers, but have * not restocked the Rx queue with fresh buffers */ rxq->read = rxq->write = 0; @@ -4457,7 +4605,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv) return 0; } -void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) +void iwl4965_rx_queue_reset(struct iwl4965_priv *priv, struct iwl4965_rx_queue *rxq) { unsigned long flags; int i; @@ -4471,7 +4619,8 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) if (rxq->pool[i].skb != NULL) { pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr, - IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + priv->hw_setting.rx_buf_size, + PCI_DMA_FROMDEVICE); priv->alloc_rxb_skb--; dev_kfree_skb(rxq->pool[i].skb); rxq->pool[i].skb = NULL; @@ -4504,7 +4653,7 @@ static u8 ratio2dB[100] = { /* Calculates a relative dB value from a ratio of linear * (i.e. not dB) signal levels. * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ -int iwl_calc_db_from_ratio(int sig_ratio) +int iwl4965_calc_db_from_ratio(int sig_ratio) { /* 1000:1 or higher just report as 60 dB */ if (sig_ratio >= 1000) @@ -4530,7 +4679,7 @@ int iwl_calc_db_from_ratio(int sig_ratio) /* Calculate an indication of rx signal quality (a percentage, not dBm!). * See http://www.ces.clemson.edu/linux/signal_quality.shtml for info * about formulas used below. */ -int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) +int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm) { int sig_qual; int degradation = PERFECT_RSSI - rssi_dbm; @@ -4565,32 +4714,39 @@ int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm) } /** - * iwl_rx_handle - Main entry function for receiving responses from the uCode + * iwl4965_rx_handle - Main entry function for receiving responses from uCode * * Uses the priv->rx_handlers callback function array to invoke * the appropriate handlers, including command responses, * frame-received notifications, and other notifications. */ -static void iwl_rx_handle(struct iwl_priv *priv) +static void iwl4965_rx_handle(struct iwl4965_priv *priv) { - struct iwl_rx_mem_buffer *rxb; - struct iwl_rx_packet *pkt; - struct iwl_rx_queue *rxq = &priv->rxq; + struct iwl4965_rx_mem_buffer *rxb; + struct iwl4965_rx_packet *pkt; + struct iwl4965_rx_queue *rxq = &priv->rxq; u32 r, i; int reclaim; unsigned long flags; + u8 fill_rx = 0; + u32 count = 0; - r = iwl_hw_get_rx_read(priv); + /* uCode's read index (stored in shared DRAM) indicates the last Rx + * buffer that the driver may process (last buffer filled by ucode). */ + r = iwl4965_hw_get_rx_read(priv); i = rxq->read; /* Rx interrupt, but nothing sent from uCode */ if (i == r) IWL_DEBUG(IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d\n", r, i); + if (iwl4965_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) + fill_rx = 1; + while (i != r) { rxb = rxq->queue[i]; - /* If an RXB doesn't have a queue slot associated with it + /* If an RXB doesn't have a Rx queue slot associated with it, * then a bug has been introduced in the queue refilling * routines -- catch it here */ BUG_ON(rxb == NULL); @@ -4598,9 +4754,9 @@ static void iwl_rx_handle(struct iwl_priv *priv) rxq->queue[i] = NULL; pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, - IWL_RX_BUF_SIZE, + priv->hw_setting.rx_buf_size, PCI_DMA_FROMDEVICE); - pkt = (struct iwl_rx_packet *)rxb->skb->data; + pkt = (struct iwl4965_rx_packet *)rxb->skb->data; /* Reclaim a command buffer only if this packet is a response * to a (driver-originated) command. @@ -4617,7 +4773,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) /* Based on type of command response or notification, * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ + * rx_handlers table. See iwl4965_setup_rx_handlers() */ if (priv->rx_handlers[pkt->hdr.cmd]) { IWL_DEBUG(IWL_DL_HOST_COMMAND | IWL_DL_RX | IWL_DL_ISR, "r = %d, i = %d, %s, 0x%02x\n", r, i, @@ -4632,11 +4788,11 @@ static void iwl_rx_handle(struct iwl_priv *priv) } if (reclaim) { - /* Invoke any callbacks, transfer the skb to caller, - * and fire off the (possibly) blocking iwl_send_cmd() + /* Invoke any callbacks, transfer the skb to caller, and + * fire off the (possibly) blocking iwl4965_send_cmd() * as we reclaim the driver command queue */ if (rxb && rxb->skb) - iwl_tx_cmd_complete(priv, rxb); + iwl4965_tx_cmd_complete(priv, rxb); else IWL_WARNING("Claim null rxb?\n"); } @@ -4651,20 +4807,34 @@ static void iwl_rx_handle(struct iwl_priv *priv) } pci_unmap_single(priv->pci_dev, rxb->dma_addr, - IWL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + priv->hw_setting.rx_buf_size, + PCI_DMA_FROMDEVICE); spin_lock_irqsave(&rxq->lock, flags); list_add_tail(&rxb->list, &priv->rxq.rx_used); spin_unlock_irqrestore(&rxq->lock, flags); i = (i + 1) & RX_QUEUE_MASK; + /* If there are a lot of unused frames, + * restock the Rx queue so ucode wont assert. */ + if (fill_rx) { + count++; + if (count >= 8) { + priv->rxq.read = i; + __iwl4965_rx_replenish(priv); + count = 0; + } + } } /* Backtrack one entry */ priv->rxq.read = i; - iwl_rx_queue_restock(priv); + iwl4965_rx_queue_restock(priv); } -int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl_tx_queue *txq) +/** + * iwl4965_tx_queue_update_write_ptr - Send new write index to hardware + */ +static int iwl4965_tx_queue_update_write_ptr(struct iwl4965_priv *priv, + struct iwl4965_tx_queue *txq) { u32 reg = 0; int rc = 0; @@ -4678,41 +4848,41 @@ int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, /* wake up nic if it's powered down ... * uCode will wake up, and interrupt us again, so next * time we'll skip this part. */ - reg = iwl_read32(priv, CSR_UCODE_DRV_GP1); + reg = iwl4965_read32(priv, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO("Requesting wakeup, GP1 = 0x%x\n", reg); - iwl_set_bit(priv, CSR_GP_CNTRL, + iwl4965_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); return rc; } /* restore this queue's parameters in nic hardware. */ - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted(priv, HBUS_TARG_WRPTR, - txq->q.first_empty | (txq_id << 8)); - iwl_release_restricted_access(priv); + iwl4965_write_direct32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); + iwl4965_release_nic_access(priv); /* else not in power-save mode, uCode will never sleep when we're * trying to tx (during RFKILL, we're not trying to tx). */ } else - iwl_write32(priv, HBUS_TARG_WRPTR, - txq->q.first_empty | (txq_id << 8)); + iwl4965_write32(priv, HBUS_TARG_WRPTR, + txq->q.write_ptr | (txq_id << 8)); txq->need_update = 0; return rc; } -#ifdef CONFIG_IWLWIFI_DEBUG -static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) +#ifdef CONFIG_IWL4965_DEBUG +static void iwl4965_print_rx_config_cmd(struct iwl4965_rxon_cmd *rxon) { DECLARE_MAC_BUF(mac); IWL_DEBUG_RADIO("RX CONFIG:\n"); - iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); + iwl4965_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); IWL_DEBUG_RADIO("u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); IWL_DEBUG_RADIO("u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); IWL_DEBUG_RADIO("u32 filter_flags: 0x%08x\n", @@ -4729,24 +4899,24 @@ static void iwl_print_rx_config_cmd(struct iwl_rxon_cmd *rxon) } #endif -static void iwl_enable_interrupts(struct iwl_priv *priv) +static void iwl4965_enable_interrupts(struct iwl4965_priv *priv) { IWL_DEBUG_ISR("Enabling interrupts\n"); set_bit(STATUS_INT_ENABLED, &priv->status); - iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); + iwl4965_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK); } -static inline void iwl_disable_interrupts(struct iwl_priv *priv) +static inline void iwl4965_disable_interrupts(struct iwl4965_priv *priv) { clear_bit(STATUS_INT_ENABLED, &priv->status); /* disable interrupts from uCode/NIC to host */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); + iwl4965_write32(priv, CSR_INT_MASK, 0x00000000); /* acknowledge/clear/reset any interrupts still pending * from uCode or flow handler (Rx/Tx DMA) */ - iwl_write32(priv, CSR_INT, 0xffffffff); - iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); + iwl4965_write32(priv, CSR_INT, 0xffffffff); + iwl4965_write32(priv, CSR_FH_INT_STATUS, 0xffffffff); IWL_DEBUG_ISR("Disabled interrupts\n"); } @@ -4773,7 +4943,7 @@ static const char *desc_lookup(int i) #define ERROR_START_OFFSET (1 * sizeof(u32)) #define ERROR_ELEM_SIZE (7 * sizeof(u32)) -static void iwl_dump_nic_error_log(struct iwl_priv *priv) +static void iwl4965_dump_nic_error_log(struct iwl4965_priv *priv) { u32 data2, line; u32 desc, time, count, base, data1; @@ -4782,18 +4952,18 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) base = le32_to_cpu(priv->card_alive.error_event_table_ptr); - if (!iwl_hw_valid_rtc_data_addr(base)) { + if (!iwl4965_hw_valid_rtc_data_addr(base)) { IWL_ERROR("Not valid error log pointer 0x%08X\n", base); return; } - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } - count = iwl_read_restricted_mem(priv, base); + count = iwl4965_read_targ_mem(priv, base); if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { IWL_ERROR("Start IWL Error Log Dump:\n"); @@ -4801,15 +4971,15 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) priv->status, priv->config, count); } - desc = iwl_read_restricted_mem(priv, base + 1 * sizeof(u32)); - blink1 = iwl_read_restricted_mem(priv, base + 3 * sizeof(u32)); - blink2 = iwl_read_restricted_mem(priv, base + 4 * sizeof(u32)); - ilink1 = iwl_read_restricted_mem(priv, base + 5 * sizeof(u32)); - ilink2 = iwl_read_restricted_mem(priv, base + 6 * sizeof(u32)); - data1 = iwl_read_restricted_mem(priv, base + 7 * sizeof(u32)); - data2 = iwl_read_restricted_mem(priv, base + 8 * sizeof(u32)); - line = iwl_read_restricted_mem(priv, base + 9 * sizeof(u32)); - time = iwl_read_restricted_mem(priv, base + 11 * sizeof(u32)); + desc = iwl4965_read_targ_mem(priv, base + 1 * sizeof(u32)); + blink1 = iwl4965_read_targ_mem(priv, base + 3 * sizeof(u32)); + blink2 = iwl4965_read_targ_mem(priv, base + 4 * sizeof(u32)); + ilink1 = iwl4965_read_targ_mem(priv, base + 5 * sizeof(u32)); + ilink2 = iwl4965_read_targ_mem(priv, base + 6 * sizeof(u32)); + data1 = iwl4965_read_targ_mem(priv, base + 7 * sizeof(u32)); + data2 = iwl4965_read_targ_mem(priv, base + 8 * sizeof(u32)); + line = iwl4965_read_targ_mem(priv, base + 9 * sizeof(u32)); + time = iwl4965_read_targ_mem(priv, base + 11 * sizeof(u32)); IWL_ERROR("Desc Time " "data1 data2 line\n"); @@ -4819,17 +4989,17 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv) IWL_ERROR("0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2, ilink1, ilink2); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } #define EVENT_START_OFFSET (4 * sizeof(u32)) /** - * iwl_print_event_log - Dump error event log to syslog + * iwl4965_print_event_log - Dump error event log to syslog * - * NOTE: Must be called with iwl_grab_restricted_access() already obtained! + * NOTE: Must be called with iwl4965_grab_nic_access() already obtained! */ -static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, +static void iwl4965_print_event_log(struct iwl4965_priv *priv, u32 start_idx, u32 num_events, u32 mode) { u32 i; @@ -4853,21 +5023,21 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read_restricted_mem(priv, ptr); + ev = iwl4965_read_targ_mem(priv, ptr); ptr += sizeof(u32); - time = iwl_read_restricted_mem(priv, ptr); + time = iwl4965_read_targ_mem(priv, ptr); ptr += sizeof(u32); if (mode == 0) IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ else { - data = iwl_read_restricted_mem(priv, ptr); + data = iwl4965_read_targ_mem(priv, ptr); ptr += sizeof(u32); IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); } } } -static void iwl_dump_nic_event_log(struct iwl_priv *priv) +static void iwl4965_dump_nic_event_log(struct iwl4965_priv *priv) { int rc; u32 base; /* SRAM byte address of event log header */ @@ -4878,29 +5048,29 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv) u32 size; /* # entries that we'll print */ base = le32_to_cpu(priv->card_alive.log_event_table_ptr); - if (!iwl_hw_valid_rtc_data_addr(base)) { + if (!iwl4965_hw_valid_rtc_data_addr(base)) { IWL_ERROR("Invalid event log pointer 0x%08X\n", base); return; } - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { IWL_WARNING("Can not read from adapter at this time.\n"); return; } /* event log header */ - capacity = iwl_read_restricted_mem(priv, base); - mode = iwl_read_restricted_mem(priv, base + (1 * sizeof(u32))); - num_wraps = iwl_read_restricted_mem(priv, base + (2 * sizeof(u32))); - next_entry = iwl_read_restricted_mem(priv, base + (3 * sizeof(u32))); + capacity = iwl4965_read_targ_mem(priv, base); + mode = iwl4965_read_targ_mem(priv, base + (1 * sizeof(u32))); + num_wraps = iwl4965_read_targ_mem(priv, base + (2 * sizeof(u32))); + next_entry = iwl4965_read_targ_mem(priv, base + (3 * sizeof(u32))); size = num_wraps ? capacity : next_entry; /* bail out if nothing in log */ if (size == 0) { IWL_ERROR("Start IWL Event Log Dump: nothing in log\n"); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); return; } @@ -4910,31 +5080,31 @@ static void iwl_dump_nic_event_log(struct iwl_priv *priv) /* if uCode has wrapped back to top of log, start at the oldest entry, * i.e the next one that uCode would fill. */ if (num_wraps) - iwl_print_event_log(priv, next_entry, + iwl4965_print_event_log(priv, next_entry, capacity - next_entry, mode); /* (then/else) start at top of log */ - iwl_print_event_log(priv, 0, next_entry, mode); + iwl4965_print_event_log(priv, 0, next_entry, mode); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } /** - * iwl_irq_handle_error - called for HW or SW error interrupt from card + * iwl4965_irq_handle_error - called for HW or SW error interrupt from card */ -static void iwl_irq_handle_error(struct iwl_priv *priv) +static void iwl4965_irq_handle_error(struct iwl4965_priv *priv) { - /* Set the FW error flag -- cleared on iwl_down */ + /* Set the FW error flag -- cleared on iwl4965_down */ set_bit(STATUS_FW_ERROR, &priv->status); /* Cancel currently queued command. */ clear_bit(STATUS_HCMD_ACTIVE, &priv->status); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_FW_ERRORS) { - iwl_dump_nic_error_log(priv); - iwl_dump_nic_event_log(priv); - iwl_print_rx_config_cmd(&priv->staging_rxon); +#ifdef CONFIG_IWL4965_DEBUG + if (iwl4965_debug_level & IWL_DL_FW_ERRORS) { + iwl4965_dump_nic_error_log(priv); + iwl4965_dump_nic_event_log(priv); + iwl4965_print_rx_config_cmd(&priv->staging_rxon); } #endif @@ -4948,7 +5118,7 @@ static void iwl_irq_handle_error(struct iwl_priv *priv) IWL_DEBUG(IWL_DL_INFO | IWL_DL_FW_ERRORS, "Restarting adapter due to uCode error.\n"); - if (iwl_is_associated(priv)) { + if (iwl4965_is_associated(priv)) { memcpy(&priv->recovery_rxon, &priv->active_rxon, sizeof(priv->recovery_rxon)); priv->error_recovering = 1; @@ -4957,16 +5127,16 @@ static void iwl_irq_handle_error(struct iwl_priv *priv) } } -static void iwl_error_recovery(struct iwl_priv *priv) +static void iwl4965_error_recovery(struct iwl4965_priv *priv) { unsigned long flags; memcpy(&priv->staging_rxon, &priv->recovery_rxon, sizeof(priv->staging_rxon)); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); - iwl_rxon_add_station(priv, priv->bssid, 1); + iwl4965_rxon_add_station(priv, priv->bssid, 1); spin_lock_irqsave(&priv->lock, flags); priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id); @@ -4974,12 +5144,12 @@ static void iwl_error_recovery(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static void iwl_irq_tasklet(struct iwl_priv *priv) +static void iwl4965_irq_tasklet(struct iwl4965_priv *priv) { u32 inta, handled = 0; u32 inta_fh; unsigned long flags; -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG u32 inta_mask; #endif @@ -4988,18 +5158,19 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Ack/clear/reset pending uCode interrupts. * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS, * and will clear only when CSR_FH_INT_STATUS gets cleared. */ - inta = iwl_read32(priv, CSR_INT); - iwl_write32(priv, CSR_INT, inta); + inta = iwl4965_read32(priv, CSR_INT); + iwl4965_write32(priv, CSR_INT, inta); /* Ack/clear/reset pending flow-handler (DMA) interrupts. * Any new interrupts that happen after this, either while we're * in this tasklet, or later, will show up in next ISR/tasklet. */ - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); - iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); + inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS); + iwl4965_write32(priv, CSR_FH_INT_STATUS, inta_fh); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & IWL_DL_ISR) { - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ +#ifdef CONFIG_IWL4965_DEBUG + if (iwl4965_debug_level & IWL_DL_ISR) { + /* just for debug */ + inta_mask = iwl4965_read32(priv, CSR_INT_MASK); IWL_DEBUG_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); } @@ -5019,9 +5190,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) IWL_ERROR("Microcode HW error detected. Restarting.\n"); /* Tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl4965_disable_interrupts(priv); - iwl_irq_handle_error(priv); + iwl4965_irq_handle_error(priv); handled |= CSR_INT_BIT_HW_ERR; @@ -5030,8 +5201,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) return; } -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { +#ifdef CONFIG_IWL4965_DEBUG + if (iwl4965_debug_level & (IWL_DL_ISR)) { /* NIC fires this, but we don't use it, redundant with WAKEUP */ if (inta & CSR_INT_BIT_MAC_CLK_ACTV) IWL_DEBUG_ISR("Microcode started or stopped.\n"); @@ -5044,10 +5215,10 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Safely ignore these bits for debug checks below */ inta &= ~(CSR_INT_BIT_MAC_CLK_ACTV | CSR_INT_BIT_ALIVE); - /* HW RF KILL switch toggled (4965 only) */ + /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { int hw_rf_kill = 0; - if (!(iwl_read32(priv, CSR_GP_CNTRL) & + if (!(iwl4965_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; @@ -5058,14 +5229,14 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) /* Queue restart only if RF_KILL switch was set to "kill" * when we loaded driver, and is now set to "enable". * After we're Alive, RF_KILL gets handled by - * iwl_rx_card_state_notif() */ + * iwl4965_rx_card_state_notif() */ if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) queue_work(priv->workqueue, &priv->restart); handled |= CSR_INT_BIT_RF_KILL; } - /* Chip got too hot and stopped itself (4965 only) */ + /* Chip got too hot and stopped itself */ if (inta & CSR_INT_BIT_CT_KILL) { IWL_ERROR("Microcode CT kill error detected.\n"); handled |= CSR_INT_BIT_CT_KILL; @@ -5075,20 +5246,20 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) if (inta & CSR_INT_BIT_SW_ERR) { IWL_ERROR("Microcode SW error detected. Restarting 0x%X.\n", inta); - iwl_irq_handle_error(priv); + iwl4965_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } /* uCode wakes up after power-down sleep */ if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR("Wakeup interrupt\n"); - iwl_rx_queue_update_write_ptr(priv, &priv->rxq); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[0]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[1]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[2]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[3]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[4]); - iwl_tx_queue_update_write_ptr(priv, &priv->txq[5]); + iwl4965_rx_queue_update_write_ptr(priv, &priv->rxq); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[0]); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[1]); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[2]); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[3]); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[4]); + iwl4965_tx_queue_update_write_ptr(priv, &priv->txq[5]); handled |= CSR_INT_BIT_WAKEUP; } @@ -5097,7 +5268,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) * Rx "responses" (frame-received notification), and other * notifications from uCode come through here*/ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { - iwl_rx_handle(priv); + iwl4965_rx_handle(priv); handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); } @@ -5116,13 +5287,13 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) } /* Re-enable all interrupts */ - iwl_enable_interrupts(priv); + iwl4965_enable_interrupts(priv); -#ifdef CONFIG_IWLWIFI_DEBUG - if (iwl_debug_level & (IWL_DL_ISR)) { - inta = iwl_read32(priv, CSR_INT); - inta_mask = iwl_read32(priv, CSR_INT_MASK); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); +#ifdef CONFIG_IWL4965_DEBUG + if (iwl4965_debug_level & (IWL_DL_ISR)) { + inta = iwl4965_read32(priv, CSR_INT); + inta_mask = iwl4965_read32(priv, CSR_INT_MASK); + inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS); IWL_DEBUG_ISR("End inta 0x%08x, enabled 0x%08x, fh 0x%08x, " "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags); } @@ -5130,9 +5301,9 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); } -static irqreturn_t iwl_isr(int irq, void *data) +static irqreturn_t iwl4965_isr(int irq, void *data) { - struct iwl_priv *priv = data; + struct iwl4965_priv *priv = data; u32 inta, inta_mask; u32 inta_fh; if (!priv) @@ -5144,12 +5315,12 @@ static irqreturn_t iwl_isr(int irq, void *data) * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(priv, CSR_INT_MASK); /* just for debug */ - iwl_write32(priv, CSR_INT_MASK, 0x00000000); + inta_mask = iwl4965_read32(priv, CSR_INT_MASK); /* just for debug */ + iwl4965_write32(priv, CSR_INT_MASK, 0x00000000); /* Discover which interrupts are active/pending */ - inta = iwl_read32(priv, CSR_INT); - inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); + inta = iwl4965_read32(priv, CSR_INT); + inta_fh = iwl4965_read32(priv, CSR_FH_INT_STATUS); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, @@ -5169,7 +5340,7 @@ static irqreturn_t iwl_isr(int irq, void *data) IWL_DEBUG_ISR("ISR inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", inta, inta_mask, inta_fh); - /* iwl_irq_tasklet() will service interrupts and re-enable them */ + /* iwl4965_irq_tasklet() will service interrupts and re-enable them */ tasklet_schedule(&priv->irq_tasklet); unplugged: @@ -5178,18 +5349,18 @@ static irqreturn_t iwl_isr(int irq, void *data) none: /* re-enable interrupts here since we don't have anything to service. */ - iwl_enable_interrupts(priv); + iwl4965_enable_interrupts(priv); spin_unlock(&priv->lock); return IRQ_NONE; } /************************** EEPROM BANDS **************************** * - * The iwl_eeprom_band definitions below provide the mapping from the + * The iwl4965_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 + * For example, iwl4965_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. @@ -5215,76 +5386,77 @@ static irqreturn_t iwl_isr(int irq, void *data) *********************************************************************/ /* 2.4 GHz */ -static const u8 iwl_eeprom_band_1[14] = { +static const u8 iwl4965_eeprom_band_1[14] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; /* 5.2 GHz bands */ -static const u8 iwl_eeprom_band_2[] = { +static const u8 iwl4965_eeprom_band_2[] = { /* 4915-5080MHz */ 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16 }; -static const u8 iwl_eeprom_band_3[] = { /* 5205-5320MHz */ +static const u8 iwl4965_eeprom_band_3[] = { /* 5170-5320MHz */ 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64 }; -static const u8 iwl_eeprom_band_4[] = { /* 5500-5700MHz */ +static const u8 iwl4965_eeprom_band_4[] = { /* 5500-5700MHz */ 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 }; -static const u8 iwl_eeprom_band_5[] = { /* 5725-5825MHz */ +static const u8 iwl4965_eeprom_band_5[] = { /* 5725-5825MHz */ 145, 149, 153, 157, 161, 165 }; -static u8 iwl_eeprom_band_6[] = { /* 2.4 FAT channel */ +static u8 iwl4965_eeprom_band_6[] = { /* 2.4 FAT channel */ 1, 2, 3, 4, 5, 6, 7 }; -static u8 iwl_eeprom_band_7[] = { /* 5.2 FAT channel */ +static u8 iwl4965_eeprom_band_7[] = { /* 5.2 FAT channel */ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 }; -static void iwl_init_band_reference(const struct iwl_priv *priv, int band, +static void iwl4965_init_band_reference(const struct iwl4965_priv *priv, + int band, int *eeprom_ch_count, - const struct iwl_eeprom_channel + const struct iwl4965_eeprom_channel **eeprom_ch_info, const u8 **eeprom_ch_index) { switch (band) { case 1: /* 2.4GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_1); *eeprom_ch_info = priv->eeprom.band_1_channels; - *eeprom_ch_index = iwl_eeprom_band_1; + *eeprom_ch_index = iwl4965_eeprom_band_1; break; - case 2: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); + case 2: /* 4.9GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_2); *eeprom_ch_info = priv->eeprom.band_2_channels; - *eeprom_ch_index = iwl_eeprom_band_2; + *eeprom_ch_index = iwl4965_eeprom_band_2; break; case 3: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_3); *eeprom_ch_info = priv->eeprom.band_3_channels; - *eeprom_ch_index = iwl_eeprom_band_3; + *eeprom_ch_index = iwl4965_eeprom_band_3; break; - case 4: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); + case 4: /* 5.5GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_4); *eeprom_ch_info = priv->eeprom.band_4_channels; - *eeprom_ch_index = iwl_eeprom_band_4; + *eeprom_ch_index = iwl4965_eeprom_band_4; break; - case 5: /* 5.2GHz band */ - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); + case 5: /* 5.7GHz band */ + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_5); *eeprom_ch_info = priv->eeprom.band_5_channels; - *eeprom_ch_index = iwl_eeprom_band_5; + *eeprom_ch_index = iwl4965_eeprom_band_5; break; - case 6: - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); + case 6: /* 2.4GHz FAT channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_6); *eeprom_ch_info = priv->eeprom.band_24_channels; - *eeprom_ch_index = iwl_eeprom_band_6; + *eeprom_ch_index = iwl4965_eeprom_band_6; break; - case 7: - *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); + case 7: /* 5 GHz FAT channels */ + *eeprom_ch_count = ARRAY_SIZE(iwl4965_eeprom_band_7); *eeprom_ch_info = priv->eeprom.band_52_channels; - *eeprom_ch_index = iwl_eeprom_band_7; + *eeprom_ch_index = iwl4965_eeprom_band_7; break; default: BUG(); @@ -5292,7 +5464,12 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, int band, } } -const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, +/** + * iwl4965_get_channel_info - Find driver's private channel info + * + * Based on band and channel number. + */ +const struct iwl4965_channel_info *iwl4965_get_channel_info(const struct iwl4965_priv *priv, int phymode, u16 channel) { int i; @@ -5319,13 +5496,16 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, #define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") -static int iwl_init_channel_map(struct iwl_priv *priv) +/** + * iwl4965_init_channel_map - Set up driver's info for all possible channels + */ +static int iwl4965_init_channel_map(struct iwl4965_priv *priv) { int eeprom_ch_count = 0; const u8 *eeprom_ch_index = NULL; - const struct iwl_eeprom_channel *eeprom_ch_info = NULL; + const struct iwl4965_eeprom_channel *eeprom_ch_info = NULL; int band, ch; - struct iwl_channel_info *ch_info; + struct iwl4965_channel_info *ch_info; if (priv->channel_count) { IWL_DEBUG_INFO("Channel map already initialized.\n"); @@ -5341,15 +5521,15 @@ static int iwl_init_channel_map(struct iwl_priv *priv) IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n"); priv->channel_count = - ARRAY_SIZE(iwl_eeprom_band_1) + - ARRAY_SIZE(iwl_eeprom_band_2) + - ARRAY_SIZE(iwl_eeprom_band_3) + - ARRAY_SIZE(iwl_eeprom_band_4) + - ARRAY_SIZE(iwl_eeprom_band_5); + ARRAY_SIZE(iwl4965_eeprom_band_1) + + ARRAY_SIZE(iwl4965_eeprom_band_2) + + ARRAY_SIZE(iwl4965_eeprom_band_3) + + ARRAY_SIZE(iwl4965_eeprom_band_4) + + ARRAY_SIZE(iwl4965_eeprom_band_5); IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count); - priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) * + priv->channel_info = kzalloc(sizeof(struct iwl4965_channel_info) * priv->channel_count, GFP_KERNEL); if (!priv->channel_info) { IWL_ERROR("Could not allocate channel_info\n"); @@ -5364,7 +5544,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv) * what just in the EEPROM) */ for (band = 1; band <= 5; band++) { - iwl_init_band_reference(priv, band, &eeprom_ch_count, + iwl4965_init_band_reference(priv, band, &eeprom_ch_count, &eeprom_ch_info, &eeprom_ch_index); /* Loop through each band adding each of the channels */ @@ -5428,14 +5608,17 @@ static int iwl_init_channel_map(struct iwl_priv *priv) } } + /* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */ for (band = 6; band <= 7; band++) { int phymode; u8 fat_extension_chan; - iwl_init_band_reference(priv, band, &eeprom_ch_count, + iwl4965_init_band_reference(priv, band, &eeprom_ch_count, &eeprom_ch_info, &eeprom_ch_index); + /* EEPROM band 6 is 2.4, band 7 is 5 GHz */ phymode = (band == 6) ? MODE_IEEE80211B : MODE_IEEE80211A; + /* Loop through each band adding each of the channels */ for (ch = 0; ch < eeprom_ch_count; ch++) { @@ -5447,11 +5630,13 @@ static int iwl_init_channel_map(struct iwl_priv *priv) else fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; + /* Set up driver's info for lower half */ iwl4965_set_fat_chan_info(priv, phymode, eeprom_ch_index[ch], &(eeprom_ch_info[ch]), fat_extension_chan); + /* Set up driver's info for upper half */ iwl4965_set_fat_chan_info(priv, phymode, (eeprom_ch_index[ch] + 4), &(eeprom_ch_info[ch]), @@ -5485,7 +5670,7 @@ static int iwl_init_channel_map(struct iwl_priv *priv) #define IWL_PASSIVE_DWELL_BASE (100) #define IWL_CHANNEL_TUNE_TIME 5 -static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode) +static inline u16 iwl4965_get_active_dwell_time(struct iwl4965_priv *priv, int phymode) { if (phymode == MODE_IEEE80211A) return IWL_ACTIVE_DWELL_TIME_52; @@ -5493,14 +5678,14 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, int phymode) return IWL_ACTIVE_DWELL_TIME_24; } -static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode) +static u16 iwl4965_get_passive_dwell_time(struct iwl4965_priv *priv, int phymode) { - u16 active = iwl_get_active_dwell_time(priv, phymode); + u16 active = iwl4965_get_active_dwell_time(priv, phymode); u16 passive = (phymode != MODE_IEEE80211A) ? IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - if (iwl_is_associated(priv)) { + if (iwl4965_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) */ @@ -5516,30 +5701,30 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, int phymode) return passive; } -static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, +static int iwl4965_get_channels_for_scan(struct iwl4965_priv *priv, int phymode, u8 is_active, u8 direct_mask, - struct iwl_scan_channel *scan_ch) + struct iwl4965_scan_channel *scan_ch) { const struct ieee80211_channel *channels = NULL; const struct ieee80211_hw_mode *hw_mode; - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; u16 passive_dwell = 0; u16 active_dwell = 0; int added, i; - hw_mode = iwl_get_hw_mode(priv, phymode); + hw_mode = iwl4965_get_hw_mode(priv, phymode); if (!hw_mode) return 0; channels = hw_mode->channels; - active_dwell = iwl_get_active_dwell_time(priv, phymode); - passive_dwell = iwl_get_passive_dwell_time(priv, phymode); + active_dwell = iwl4965_get_active_dwell_time(priv, phymode); + passive_dwell = iwl4965_get_passive_dwell_time(priv, phymode); for (i = 0, added = 0; i < hw_mode->num_channels; i++) { if (channels[i].chan == le16_to_cpu(priv->active_rxon.channel)) { - if (iwl_is_associated(priv)) { + if (iwl4965_is_associated(priv)) { IWL_DEBUG_SCAN ("Skipping current channel %d\n", le16_to_cpu(priv->active_rxon.channel)); @@ -5550,7 +5735,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, scan_ch->channel = channels[i].chan; - ch_info = iwl_get_channel_info(priv, phymode, scan_ch->channel); + ch_info = iwl4965_get_channel_info(priv, phymode, + scan_ch->channel); if (!is_channel_valid(ch_info)) { IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", scan_ch->channel); @@ -5572,7 +5758,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, scan_ch->active_dwell = cpu_to_le16(active_dwell); scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - /* Set power levels to defaults */ + /* Set txpower levels to defaults */ scan_ch->tpc.dsp_atten = 110; /* scan_pwr_info->tpc.dsp_atten; */ @@ -5582,8 +5768,8 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, else { scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level - scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3; + * power level: + * scan_ch->tpc.tx_gain = ((1<<5) | (2 << 3)) | 3; */ } @@ -5601,7 +5787,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, int phymode, return added; } -static void iwl_reset_channel_flag(struct iwl_priv *priv) +static void iwl4965_reset_channel_flag(struct iwl4965_priv *priv) { int i, j; for (i = 0; i < 3; i++) { @@ -5611,13 +5797,13 @@ static void iwl_reset_channel_flag(struct iwl_priv *priv) } } -static void iwl_init_hw_rates(struct iwl_priv *priv, +static void iwl4965_init_hw_rates(struct iwl4965_priv *priv, struct ieee80211_rate *rates) { int i; for (i = 0; i < IWL_RATE_COUNT; i++) { - rates[i].rate = iwl_rates[i].ieee * 5; + rates[i].rate = iwl4965_rates[i].ieee * 5; rates[i].val = i; /* Rate scaling will work on indexes */ rates[i].val2 = i; rates[i].flags = IEEE80211_RATE_SUPPORTED; @@ -5629,7 +5815,7 @@ static void iwl_init_hw_rates(struct iwl_priv *priv, * If CCK 1M then set rate flag to CCK else CCK_2 * which is CCK | PREAMBLE2 */ - rates[i].flags |= (iwl_rates[i].plcp == 10) ? + rates[i].flags |= (iwl4965_rates[i].plcp == 10) ? IEEE80211_RATE_CCK : IEEE80211_RATE_CCK_2; } @@ -5637,16 +5823,14 @@ static void iwl_init_hw_rates(struct iwl_priv *priv, if (IWL_BASIC_RATES_MASK & (1 << i)) rates[i].flags |= IEEE80211_RATE_BASIC; } - - iwl4965_init_hw_rates(priv, rates); } /** - * iwl_init_geos - Initialize mac80211's geo/channel info based from eeprom + * iwl4965_init_geos - Initialize mac80211's geo/channel info based from eeprom */ -static int iwl_init_geos(struct iwl_priv *priv) +static int iwl4965_init_geos(struct iwl4965_priv *priv) { - struct iwl_channel_info *ch; + struct iwl4965_channel_info *ch; struct ieee80211_hw_mode *modes; struct ieee80211_channel *channels; struct ieee80211_channel *geo_ch; @@ -5656,10 +5840,8 @@ static int iwl_init_geos(struct iwl_priv *priv) A = 0, B = 1, G = 2, - A_11N = 3, - G_11N = 4, }; - int mode_count = 5; + int mode_count = 3; if (priv->modes) { IWL_DEBUG_INFO("Geography modes already initialized.\n"); @@ -5694,11 +5876,14 @@ static int iwl_init_geos(struct iwl_priv *priv) /* 5.2GHz channels start after the 2.4GHz channels */ modes[A].mode = MODE_IEEE80211A; - modes[A].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; + modes[A].channels = &channels[ARRAY_SIZE(iwl4965_eeprom_band_1)]; modes[A].rates = rates; modes[A].num_rates = 8; /* just OFDM */ modes[A].rates = &rates[4]; modes[A].num_channels = 0; +#ifdef CONFIG_IWL4965_HT + iwl4965_init_ht_hw_capab(&modes[A].ht_info, MODE_IEEE80211A); +#endif modes[B].mode = MODE_IEEE80211B; modes[B].channels = channels; @@ -5711,23 +5896,14 @@ static int iwl_init_geos(struct iwl_priv *priv) modes[G].rates = rates; modes[G].num_rates = 12; /* OFDM & CCK */ modes[G].num_channels = 0; - - modes[G_11N].mode = MODE_IEEE80211G; - modes[G_11N].channels = channels; - modes[G_11N].num_rates = 13; /* OFDM & CCK */ - modes[G_11N].rates = rates; - modes[G_11N].num_channels = 0; - - modes[A_11N].mode = MODE_IEEE80211A; - modes[A_11N].channels = &channels[ARRAY_SIZE(iwl_eeprom_band_1)]; - modes[A_11N].rates = &rates[4]; - modes[A_11N].num_rates = 9; /* just OFDM */ - modes[A_11N].num_channels = 0; +#ifdef CONFIG_IWL4965_HT + iwl4965_init_ht_hw_capab(&modes[G].ht_info, MODE_IEEE80211G); +#endif priv->ieee_channels = channels; priv->ieee_rates = rates; - iwl_init_hw_rates(priv, rates); + iwl4965_init_hw_rates(priv, rates); for (i = 0, geo_ch = channels; i < priv->channel_count; i++) { ch = &priv->channel_info[i]; @@ -5742,11 +5918,9 @@ static int iwl_init_geos(struct iwl_priv *priv) if (is_channel_a_band(ch)) { geo_ch = &modes[A].channels[modes[A].num_channels++]; - modes[A_11N].num_channels++; } else { geo_ch = &modes[B].channels[modes[B].num_channels++]; modes[G].num_channels++; - modes[G_11N].num_channels++; } geo_ch->freq = ieee80211chan2mhz(ch->channel); @@ -5812,7 +5986,7 @@ static int iwl_init_geos(struct iwl_priv *priv) * ******************************************************************************/ -static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) +static void iwl4965_dealloc_ucode_pci(struct iwl4965_priv *priv) { if (priv->ucode_code.v_addr != NULL) { pci_free_consistent(priv->pci_dev, @@ -5859,10 +6033,11 @@ static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) } /** - * iwl_verify_inst_full - verify runtime uCode image in card vs. host, + * iwl4965_verify_inst_full - verify runtime uCode image in card vs. host, * looking at all data. */ -static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) +static int iwl4965_verify_inst_full(struct iwl4965_priv *priv, __le32 * image, + u32 len) { u32 val; u32 save_len = len; @@ -5871,18 +6046,18 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) IWL_DEBUG_INFO("ucode inst image size is %u\n", len); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); + iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, RTC_INST_LOWER_BOUND); errcnt = 0; for (; len > 0; len -= sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT); + val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { IWL_ERROR("uCode INST section is invalid at " "offset 0x%x, is 0x%x, s/b 0x%x\n", @@ -5894,7 +6069,7 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) } } - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); if (!errcnt) IWL_DEBUG_INFO @@ -5905,11 +6080,11 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 * image, u32 len) /** - * iwl_verify_inst_sparse - verify runtime uCode image in card vs. host, + * iwl4965_verify_inst_sparse - verify runtime uCode image in card vs. host, * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) +static int iwl4965_verify_inst_sparse(struct iwl4965_priv *priv, __le32 *image, u32 len) { u32 val; int rc = 0; @@ -5918,7 +6093,7 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) IWL_DEBUG_INFO("ucode inst image size is %u\n", len); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) return rc; @@ -5926,9 +6101,9 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_restricted(priv, HBUS_TARG_MEM_RADDR, + iwl4965_write_direct32(priv, HBUS_TARG_MEM_RADDR, i + RTC_INST_LOWER_BOUND); - val = _iwl_read_restricted(priv, HBUS_TARG_MEM_RDAT); + val = _iwl4965_read_direct32(priv, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { #if 0 /* Enable this if you want to see details */ IWL_ERROR("uCode INST section is invalid at " @@ -5942,17 +6117,17 @@ static int iwl_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len) } } - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); return rc; } /** - * iwl_verify_ucode - determine which instruction image is in SRAM, + * iwl4965_verify_ucode - determine which instruction image is in SRAM, * and verify its contents */ -static int iwl_verify_ucode(struct iwl_priv *priv) +static int iwl4965_verify_ucode(struct iwl4965_priv *priv) { __le32 *image; u32 len; @@ -5961,7 +6136,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try bootstrap */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl4965_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Bootstrap uCode is good in inst SRAM\n"); return 0; @@ -5970,7 +6145,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try initialize */ image = (__le32 *)priv->ucode_init.v_addr; len = priv->ucode_init.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl4965_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Initialize uCode is good in inst SRAM\n"); return 0; @@ -5979,7 +6154,7 @@ static int iwl_verify_ucode(struct iwl_priv *priv) /* Try runtime/protocol */ image = (__le32 *)priv->ucode_code.v_addr; len = priv->ucode_code.len; - rc = iwl_verify_inst_sparse(priv, image, len); + rc = iwl4965_verify_inst_sparse(priv, image, len); if (rc == 0) { IWL_DEBUG_INFO("Runtime uCode is good in inst SRAM\n"); return 0; @@ -5987,18 +6162,19 @@ static int iwl_verify_ucode(struct iwl_priv *priv) IWL_ERROR("NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n"); - /* Show first several data entries in instruction SRAM. - * Selection of bootstrap image is arbitrary. */ + /* Since nothing seems to match, show first several data entries in + * instruction SRAM, so maybe visual inspection will give a clue. + * Selection of bootstrap image (vs. other images) is arbitrary. */ image = (__le32 *)priv->ucode_boot.v_addr; len = priv->ucode_boot.len; - rc = iwl_verify_inst_full(priv, image, len); + rc = iwl4965_verify_inst_full(priv, image, len); return rc; } /* check contents of special bootstrap uCode SRAM */ -static int iwl_verify_bsm(struct iwl_priv *priv) +static int iwl4965_verify_bsm(struct iwl4965_priv *priv) { __le32 *image = priv->ucode_boot.v_addr; u32 len = priv->ucode_boot.len; @@ -6008,11 +6184,11 @@ static int iwl_verify_bsm(struct iwl_priv *priv) IWL_DEBUG_INFO("Begin verify bsm\n"); /* verify BSM SRAM contents */ - val = iwl_read_restricted_reg(priv, BSM_WR_DWCOUNT_REG); + val = iwl4965_read_prph(priv, BSM_WR_DWCOUNT_REG); for (reg = BSM_SRAM_LOWER_BOUND; reg < BSM_SRAM_LOWER_BOUND + len; reg += sizeof(u32), image ++) { - val = iwl_read_restricted_reg(priv, reg); + val = iwl4965_read_prph(priv, reg); if (val != le32_to_cpu(*image)) { IWL_ERROR("BSM uCode verification failed at " "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n", @@ -6029,7 +6205,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv) } /** - * iwl_load_bsm - Load bootstrap instructions + * iwl4965_load_bsm - Load bootstrap instructions * * BSM operation: * @@ -6060,7 +6236,7 @@ static int iwl_verify_bsm(struct iwl_priv *priv) * the runtime uCode instructions and the backup data cache into SRAM, * and re-launches the runtime uCode from where it left off. */ -static int iwl_load_bsm(struct iwl_priv *priv) +static int iwl4965_load_bsm(struct iwl4965_priv *priv) { __le32 *image = priv->ucode_boot.v_addr; u32 len = priv->ucode_boot.len; @@ -6080,8 +6256,8 @@ static int iwl_load_bsm(struct iwl_priv *priv) return -EINVAL; /* Tell bootstrap uCode where to find the "Initialize" uCode - * in host DRAM ... bits 31:0 for 3945, bits 35:4 for 4965. - * NOTE: iwl_initialize_alive_start() will replace these values, + * in host DRAM ... host DRAM physical address bits 35:4 for 4965. + * NOTE: iwl4965_initialize_alive_start() will replace these values, * after the "initialize" uCode has run, to point to * runtime/protocol instructions and backup data cache. */ pinst = priv->ucode_init.p_addr >> 4; @@ -6089,42 +6265,42 @@ static int iwl_load_bsm(struct iwl_priv *priv) inst_len = priv->ucode_init.len; data_len = priv->ucode_init_data.len; - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) return rc; - iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); + iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len); + iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len); /* Fill BSM memory with bootstrap instructions */ for (reg_offset = BSM_SRAM_LOWER_BOUND; reg_offset < BSM_SRAM_LOWER_BOUND + len; reg_offset += sizeof(u32), image++) - _iwl_write_restricted_reg(priv, reg_offset, + _iwl4965_write_prph(priv, reg_offset, le32_to_cpu(*image)); - rc = iwl_verify_bsm(priv); + rc = iwl4965_verify_bsm(priv); if (rc) { - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); return rc; } /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */ - iwl_write_restricted_reg(priv, BSM_WR_MEM_SRC_REG, 0x0); - iwl_write_restricted_reg(priv, BSM_WR_MEM_DST_REG, + iwl4965_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0); + iwl4965_write_prph(priv, BSM_WR_MEM_DST_REG, RTC_INST_LOWER_BOUND); - iwl_write_restricted_reg(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); + iwl4965_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32)); /* Load bootstrap code into instruction SRAM now, * to prepare to load "initialize" uCode */ - iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG, + iwl4965_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START); /* Wait for load of bootstrap uCode to finish */ for (i = 0; i < 100; i++) { - done = iwl_read_restricted_reg(priv, BSM_WR_CTRL_REG); + done = iwl4965_read_prph(priv, BSM_WR_CTRL_REG); if (!(done & BSM_WR_CTRL_REG_BIT_START)) break; udelay(10); @@ -6138,29 +6314,35 @@ static int iwl_load_bsm(struct iwl_priv *priv) /* Enable future boot loads whenever power management unit triggers it * (e.g. when powering back up after power-save shutdown) */ - iwl_write_restricted_reg(priv, BSM_WR_CTRL_REG, + iwl4965_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); return 0; } -static void iwl_nic_start(struct iwl_priv *priv) +static void iwl4965_nic_start(struct iwl4965_priv *priv) { /* Remove all resets to allow NIC to operate */ - iwl_write32(priv, CSR_RESET, 0); + iwl4965_write32(priv, CSR_RESET, 0); +} + +static int iwl4965_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) +{ + desc->v_addr = pci_alloc_consistent(pci_dev, desc->len, &desc->p_addr); + return (desc->v_addr != NULL) ? 0 : -ENOMEM; } /** - * iwl_read_ucode - Read uCode images from disk file. + * iwl4965_read_ucode - Read uCode images from disk file. * * Copy into buffers for card to fetch via bus-mastering */ -static int iwl_read_ucode(struct iwl_priv *priv) +static int iwl4965_read_ucode(struct iwl4965_priv *priv) { - struct iwl_ucode *ucode; - int rc = 0; + struct iwl4965_ucode *ucode; + int ret; const struct firmware *ucode_raw; const char *name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode"; u8 *src; @@ -6169,9 +6351,10 @@ static int iwl_read_ucode(struct iwl_priv *priv) /* Ask kernel firmware_class module to get the boot firmware off disk. * request_firmware() is synchronous, file is in memory on return. */ - rc = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); - if (rc < 0) { - IWL_ERROR("%s firmware file req failed: Reason %d\n", name, rc); + ret = request_firmware(&ucode_raw, name, &priv->pci_dev->dev); + if (ret < 0) { + IWL_ERROR("%s firmware file req failed: Reason %d\n", + name, ret); goto error; } @@ -6181,7 +6364,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) /* Make sure that we got at least our header! */ if (ucode_raw->size < sizeof(*ucode)) { IWL_ERROR("File size way too small!\n"); - rc = -EINVAL; + ret = -EINVAL; goto err_release; } @@ -6214,43 +6397,43 @@ static int iwl_read_ucode(struct iwl_priv *priv) IWL_DEBUG_INFO("uCode file size %d too small\n", (int)ucode_raw->size); - rc = -EINVAL; + ret = -EINVAL; goto err_release; } /* Verify that uCode images will fit in card's SRAM */ if (inst_size > IWL_MAX_INST_SIZE) { - IWL_DEBUG_INFO("uCode instr len %d too large to fit in card\n", - (int)inst_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode instr len %d too large to fit in\n", + inst_size); + ret = -EINVAL; goto err_release; } if (data_size > IWL_MAX_DATA_SIZE) { - IWL_DEBUG_INFO("uCode data len %d too large to fit in card\n", - (int)data_size); - rc = -EINVAL; + IWL_DEBUG_INFO("uCode data len %d too large to fit in\n", + data_size); + ret = -EINVAL; goto err_release; } if (init_size > IWL_MAX_INST_SIZE) { IWL_DEBUG_INFO - ("uCode init instr len %d too large to fit in card\n", - (int)init_size); - rc = -EINVAL; + ("uCode init instr len %d too large to fit in\n", + init_size); + ret = -EINVAL; goto err_release; } if (init_data_size > IWL_MAX_DATA_SIZE) { IWL_DEBUG_INFO - ("uCode init data len %d too large to fit in card\n", - (int)init_data_size); - rc = -EINVAL; + ("uCode init data len %d too large to fit in\n", + init_data_size); + ret = -EINVAL; goto err_release; } if (boot_size > IWL_MAX_BSM_SIZE) { IWL_DEBUG_INFO - ("uCode boot instr len %d too large to fit in bsm\n", - (int)boot_size); - rc = -EINVAL; + ("uCode boot instr len %d too large to fit in\n", + boot_size); + ret = -EINVAL; goto err_release; } @@ -6260,66 +6443,50 @@ static int iwl_read_ucode(struct iwl_priv *priv) * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ priv->ucode_code.len = inst_size; - priv->ucode_code.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_code.len, - &(priv->ucode_code.p_addr)); + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); priv->ucode_data.len = data_size; - priv->ucode_data.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_data.len, - &(priv->ucode_data.p_addr)); + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); priv->ucode_data_backup.len = data_size; - priv->ucode_data_backup.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_data_backup.len, - &(priv->ucode_data_backup.p_addr)); - + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup); /* Initialization instructions and data */ - priv->ucode_init.len = init_size; - priv->ucode_init.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_init.len, - &(priv->ucode_init.p_addr)); - - priv->ucode_init_data.len = init_data_size; - priv->ucode_init_data.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_init_data.len, - &(priv->ucode_init_data.p_addr)); + if (init_size && init_data_size) { + priv->ucode_init.len = init_size; + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); + + priv->ucode_init_data.len = init_data_size; + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); + + if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) + goto err_pci_alloc; + } /* Bootstrap (instructions only, no data) */ - priv->ucode_boot.len = boot_size; - priv->ucode_boot.v_addr = - pci_alloc_consistent(priv->pci_dev, - priv->ucode_boot.len, - &(priv->ucode_boot.p_addr)); + if (boot_size) { + priv->ucode_boot.len = boot_size; + iwl4965_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot); - if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr || - !priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr || - !priv->ucode_boot.v_addr || !priv->ucode_data_backup.v_addr) - goto err_pci_alloc; + if (!priv->ucode_boot.v_addr) + goto err_pci_alloc; + } /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ src = &ucode->data[0]; len = priv->ucode_code.len; - IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) uCode instr len %Zd\n", len); memcpy(priv->ucode_code.v_addr, src, len); IWL_DEBUG_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); /* Runtime data (2nd block) - * NOTE: Copy into backup buffer will be done in iwl_up() */ + * NOTE: Copy into backup buffer will be done in iwl4965_up() */ src = &ucode->data[inst_size]; len = priv->ucode_data.len; - IWL_DEBUG_INFO("Copying (but not loading) uCode data len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) uCode data len %Zd\n", len); memcpy(priv->ucode_data.v_addr, src, len); memcpy(priv->ucode_data_backup.v_addr, src, len); @@ -6327,8 +6494,8 @@ static int iwl_read_ucode(struct iwl_priv *priv) if (init_size) { src = &ucode->data[inst_size + data_size]; len = priv->ucode_init.len; - IWL_DEBUG_INFO("Copying (but not loading) init instr len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) init instr len %Zd\n", + len); memcpy(priv->ucode_init.v_addr, src, len); } @@ -6336,16 +6503,15 @@ static int iwl_read_ucode(struct iwl_priv *priv) if (init_data_size) { src = &ucode->data[inst_size + data_size + init_size]; len = priv->ucode_init_data.len; - IWL_DEBUG_INFO("Copying (but not loading) init data len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) init data len %Zd\n", + len); memcpy(priv->ucode_init_data.v_addr, src, len); } /* Bootstrap instructions (5th block) */ src = &ucode->data[inst_size + data_size + init_size + init_data_size]; len = priv->ucode_boot.len; - IWL_DEBUG_INFO("Copying (but not loading) boot instr len %d\n", - (int)len); + IWL_DEBUG_INFO("Copying (but not loading) boot instr len %Zd\n", len); memcpy(priv->ucode_boot.v_addr, src, len); /* We have our copies now, allow OS release its copies */ @@ -6354,19 +6520,19 @@ static int iwl_read_ucode(struct iwl_priv *priv) err_pci_alloc: IWL_ERROR("failed to allocate pci memory\n"); - rc = -ENOMEM; - iwl_dealloc_ucode_pci(priv); + ret = -ENOMEM; + iwl4965_dealloc_ucode_pci(priv); err_release: release_firmware(ucode_raw); error: - return rc; + return ret; } /** - * iwl_set_ucode_ptrs - Set uCode address location + * iwl4965_set_ucode_ptrs - Set uCode address location * * Tell initialization uCode where to find runtime uCode. * @@ -6374,7 +6540,7 @@ static int iwl_read_ucode(struct iwl_priv *priv) * We need to replace them to load runtime uCode inst and data, * and to save runtime data when powering down. */ -static int iwl_set_ucode_ptrs(struct iwl_priv *priv) +static int iwl4965_set_ucode_ptrs(struct iwl4965_priv *priv) { dma_addr_t pinst; dma_addr_t pdata; @@ -6386,24 +6552,24 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) pdata = priv->ucode_data_backup.p_addr >> 4; spin_lock_irqsave(&priv->lock, flags); - rc = iwl_grab_restricted_access(priv); + rc = iwl4965_grab_nic_access(priv); if (rc) { spin_unlock_irqrestore(&priv->lock, flags); return rc; } /* Tell bootstrap uCode where to find image to load */ - iwl_write_restricted_reg(priv, BSM_DRAM_INST_PTR_REG, pinst); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_PTR_REG, pdata); - iwl_write_restricted_reg(priv, BSM_DRAM_DATA_BYTECOUNT_REG, + iwl4965_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst); + iwl4965_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata); + iwl4965_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, priv->ucode_data.len); /* Inst bytecount must be last to set up, bit 31 signals uCode * that all new ptr/size info is in place */ - iwl_write_restricted_reg(priv, BSM_DRAM_INST_BYTECOUNT_REG, + iwl4965_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, priv->ucode_code.len | BSM_DRAM_INST_LOAD); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); spin_unlock_irqrestore(&priv->lock, flags); @@ -6413,7 +6579,7 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) } /** - * iwl_init_alive_start - Called after REPLY_ALIVE notification receieved + * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received * * Called after REPLY_ALIVE notification received from "initialize" uCode. * @@ -6423,7 +6589,7 @@ static int iwl_set_ucode_ptrs(struct iwl_priv *priv) * * Tell "initialize" uCode to go ahead and load the runtime uCode. */ -static void iwl_init_alive_start(struct iwl_priv *priv) +static void iwl4965_init_alive_start(struct iwl4965_priv *priv) { /* Check alive response for "valid" sign from uCode */ if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { @@ -6436,7 +6602,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv) /* Bootstrap uCode has loaded initialize uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "initialize" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl4965_verify_ucode(priv)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Bad \"initialize\" uCode load.\n"); @@ -6450,7 +6616,7 @@ static void iwl_init_alive_start(struct iwl_priv *priv) * load and launch runtime uCode, which will send us another "Alive" * notification. */ IWL_DEBUG_INFO("Initialization Alive received.\n"); - if (iwl_set_ucode_ptrs(priv)) { + if (iwl4965_set_ucode_ptrs(priv)) { /* Runtime instruction load won't happen; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Couldn't set up uCode pointers.\n"); @@ -6464,11 +6630,11 @@ static void iwl_init_alive_start(struct iwl_priv *priv) /** - * iwl_alive_start - called after REPLY_ALIVE notification received + * iwl4965_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's - * Alive gets handled by iwl_init_alive_start()). + * Alive gets handled by iwl4965_init_alive_start()). */ -static void iwl_alive_start(struct iwl_priv *priv) +static void iwl4965_alive_start(struct iwl4965_priv *priv) { int rc = 0; @@ -6484,14 +6650,14 @@ static void iwl_alive_start(struct iwl_priv *priv) /* Initialize uCode has loaded Runtime uCode ... verify inst image. * This is a paranoid check, because we would not have gotten the * "runtime" alive if code weren't properly loaded. */ - if (iwl_verify_ucode(priv)) { + if (iwl4965_verify_ucode(priv)) { /* Runtime instruction load was bad; * take it all the way back down so we can try again */ IWL_DEBUG_INFO("Bad runtime uCode load.\n"); goto restart; } - iwl_clear_stations_table(priv); + iwl4965_clear_stations_table(priv); rc = iwl4965_alive_notify(priv); if (rc) { @@ -6500,28 +6666,28 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } - /* After the ALIVE response, we can process host commands */ + /* After the ALIVE response, we can send host commands to 4965 uCode */ set_bit(STATUS_ALIVE, &priv->status); /* Clear out the uCode error bit if it is set */ clear_bit(STATUS_FW_ERROR, &priv->status); - rc = iwl_init_channel_map(priv); + rc = iwl4965_init_channel_map(priv); if (rc) { IWL_ERROR("initializing regulatory failed: %d\n", rc); return; } - iwl_init_geos(priv); + iwl4965_init_geos(priv); - if (iwl_is_rfkill(priv)) + if (iwl4965_is_rfkill(priv)) return; if (!priv->mac80211_registered) { /* Unlock so any user space entry points can call back into * the driver without a deadlock... */ mutex_unlock(&priv->mutex); - iwl_rate_control_register(priv->hw); + iwl4965_rate_control_register(priv->hw); rc = ieee80211_register_hw(priv->hw); priv->hw->conf.beacon_int = 100; mutex_lock(&priv->mutex); @@ -6534,33 +6700,33 @@ static void iwl_alive_start(struct iwl_priv *priv) priv->mac80211_registered = 1; - iwl_reset_channel_flag(priv); + iwl4965_reset_channel_flag(priv); } else ieee80211_start_queues(priv->hw); priv->active_rate = priv->rates_mask; priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; - iwl_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); + iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(priv->power_mode)); - if (iwl_is_associated(priv)) { - struct iwl_rxon_cmd *active_rxon = - (struct iwl_rxon_cmd *)(&priv->active_rxon); + if (iwl4965_is_associated(priv)) { + struct iwl4965_rxon_cmd *active_rxon = + (struct iwl4965_rxon_cmd *)(&priv->active_rxon); memcpy(&priv->staging_rxon, &priv->active_rxon, sizeof(priv->staging_rxon)); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv); + iwl4965_connection_init_rx_config(priv); memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); } - /* Configure BT coexistence */ - iwl_send_bt_config(priv); + /* Configure Bluetooth device coexistence support */ + iwl4965_send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); /* At this point, the NIC is initialized and operational */ priv->notif_missed_beacons = 0; @@ -6570,7 +6736,7 @@ static void iwl_alive_start(struct iwl_priv *priv) IWL_DEBUG_INFO("ALIVE processing complete.\n"); if (priv->error_recovering) - iwl_error_recovery(priv); + iwl4965_error_recovery(priv); return; @@ -6578,9 +6744,9 @@ static void iwl_alive_start(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->restart); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv); +static void iwl4965_cancel_deferred_work(struct iwl4965_priv *priv); -static void __iwl_down(struct iwl_priv *priv) +static void __iwl4965_down(struct iwl4965_priv *priv) { unsigned long flags; int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); @@ -6593,12 +6759,12 @@ static void __iwl_down(struct iwl_priv *priv) if (!exit_pending) set_bit(STATUS_EXIT_PENDING, &priv->status); - iwl_clear_stations_table(priv); + iwl4965_clear_stations_table(priv); /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); - iwl_cancel_deferred_work(priv); + iwl4965_cancel_deferred_work(priv); /* Wipe out the EXIT_PENDING status bit if we are not actually * exiting the module */ @@ -6606,17 +6772,17 @@ static void __iwl_down(struct iwl_priv *priv) clear_bit(STATUS_EXIT_PENDING, &priv->status); /* stop and reset the on-board processor */ - iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl4965_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); /* tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl4965_disable_interrupts(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); - /* If we have not previously called iwl_init() then + /* If we have not previously called iwl4965_init() then * clear all bits but the RF Kill and SUSPEND bits and return */ - if (!iwl_is_init(priv)) { + if (!iwl4965_is_init(priv)) { priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << STATUS_RF_KILL_HW | test_bit(STATUS_RF_KILL_SW, &priv->status) << @@ -6638,47 +6804,48 @@ static void __iwl_down(struct iwl_priv *priv) STATUS_FW_ERROR; spin_lock_irqsave(&priv->lock, flags); - iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + iwl4965_clear_bit(priv, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); spin_unlock_irqrestore(&priv->lock, flags); - iwl_hw_txq_ctx_stop(priv); - iwl_hw_rxq_stop(priv); + iwl4965_hw_txq_ctx_stop(priv); + iwl4965_hw_rxq_stop(priv); spin_lock_irqsave(&priv->lock, flags); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG, + if (!iwl4965_grab_nic_access(priv)) { + iwl4965_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); - iwl_release_restricted_access(priv); + iwl4965_release_nic_access(priv); } spin_unlock_irqrestore(&priv->lock, flags); udelay(5); - iwl_hw_nic_stop_master(priv); - iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - iwl_hw_nic_reset(priv); + iwl4965_hw_nic_stop_master(priv); + iwl4965_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl4965_hw_nic_reset(priv); exit: - memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); + memset(&priv->card_alive, 0, sizeof(struct iwl4965_alive_resp)); if (priv->ibss_beacon) dev_kfree_skb(priv->ibss_beacon); priv->ibss_beacon = NULL; /* clear out any free frames */ - iwl_clear_free_frames(priv); + iwl4965_clear_free_frames(priv); } -static void iwl_down(struct iwl_priv *priv) +static void iwl4965_down(struct iwl4965_priv *priv) { mutex_lock(&priv->mutex); - __iwl_down(priv); + __iwl4965_down(priv); mutex_unlock(&priv->mutex); } #define MAX_HW_RESTARTS 5 -static int __iwl_up(struct iwl_priv *priv) +static int __iwl4965_up(struct iwl4965_priv *priv) { DECLARE_MAC_BUF(mac); int rc, i; @@ -6695,26 +6862,26 @@ static int __iwl_up(struct iwl_priv *priv) return 0; } - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF); - rc = iwl_hw_nic_init(priv); + rc = iwl4965_hw_nic_init(priv); if (rc) { IWL_ERROR("Unable to int nic\n"); return rc; } /* make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); /* clear (again), then enable host interrupts */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_enable_interrupts(priv); + iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl4965_enable_interrupts(priv); /* really make sure rfkill handshake bits are cleared */ - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Copy original ucode data image from disk into backup cache. * This will be used to initialize the on-board processor's @@ -6725,7 +6892,7 @@ static int __iwl_up(struct iwl_priv *priv) /* If platform's RF_KILL switch is set to KILL, * wait for BIT_INT_RF_KILL interrupt before loading uCode * and getting things started */ - if (!(iwl_read32(priv, CSR_GP_CNTRL) & + if (!(iwl4965_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; @@ -6736,12 +6903,12 @@ static int __iwl_up(struct iwl_priv *priv) for (i = 0; i < MAX_HW_RESTARTS; i++) { - iwl_clear_stations_table(priv); + iwl4965_clear_stations_table(priv); /* load bootstrap state machine, * load bootstrap program into processor's memory, * prepare to load the "initialize" uCode */ - rc = iwl_load_bsm(priv); + rc = iwl4965_load_bsm(priv); if (rc) { IWL_ERROR("Unable to set up bootstrap uCode: %d\n", rc); @@ -6749,9 +6916,9 @@ static int __iwl_up(struct iwl_priv *priv) } /* start card; "initialize" will load runtime ucode */ - iwl_nic_start(priv); + iwl4965_nic_start(priv); - /* MAC Address location in EEPROM same for 3945/4965 */ + /* MAC Address location in EEPROM is same for 3945/4965 */ get_eeprom_mac(priv, priv->mac_addr); IWL_DEBUG_INFO("MAC address: %s\n", print_mac(mac, priv->mac_addr)); @@ -6764,7 +6931,7 @@ static int __iwl_up(struct iwl_priv *priv) } set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); + __iwl4965_down(priv); /* tried to restart and config the device for as long as our * patience could withstand */ @@ -6779,35 +6946,35 @@ static int __iwl_up(struct iwl_priv *priv) * *****************************************************************************/ -static void iwl_bg_init_alive_start(struct work_struct *data) +static void iwl4965_bg_init_alive_start(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, init_alive_start.work); + struct iwl4965_priv *priv = + container_of(data, struct iwl4965_priv, init_alive_start.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_init_alive_start(priv); + iwl4965_init_alive_start(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_alive_start(struct work_struct *data) +static void iwl4965_bg_alive_start(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, alive_start.work); + struct iwl4965_priv *priv = + container_of(data, struct iwl4965_priv, alive_start.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_alive_start(priv); + iwl4965_alive_start(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_rf_kill(struct work_struct *work) +static void iwl4965_bg_rf_kill(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, rf_kill); wake_up_interruptible(&priv->wait_command_queue); @@ -6816,7 +6983,7 @@ static void iwl_bg_rf_kill(struct work_struct *work) mutex_lock(&priv->mutex); - if (!iwl_is_rfkill(priv)) { + if (!iwl4965_is_rfkill(priv)) { IWL_DEBUG(IWL_DL_INFO | IWL_DL_RF_KILL, "HW and/or SW RF Kill no longer active, restarting " "device\n"); @@ -6837,10 +7004,10 @@ static void iwl_bg_rf_kill(struct work_struct *work) #define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) -static void iwl_bg_scan_check(struct work_struct *data) +static void iwl4965_bg_scan_check(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, scan_check.work); + struct iwl4965_priv *priv = + container_of(data, struct iwl4965_priv, scan_check.work); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -6853,22 +7020,22 @@ static void iwl_bg_scan_check(struct work_struct *data) jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - iwl_send_scan_abort(priv); + iwl4965_send_scan_abort(priv); } mutex_unlock(&priv->mutex); } -static void iwl_bg_request_scan(struct work_struct *data) +static void iwl4965_bg_request_scan(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, request_scan); - struct iwl_host_cmd cmd = { + struct iwl4965_priv *priv = + container_of(data, struct iwl4965_priv, request_scan); + struct iwl4965_host_cmd cmd = { .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl_scan_cmd), + .len = sizeof(struct iwl4965_scan_cmd), .meta.flags = CMD_SIZE_HUGE, }; int rc = 0; - struct iwl_scan_cmd *scan; + struct iwl4965_scan_cmd *scan; struct ieee80211_conf *conf = NULL; u8 direct_mask; int phymode; @@ -6877,7 +7044,7 @@ static void iwl_bg_request_scan(struct work_struct *data) mutex_lock(&priv->mutex); - if (!iwl_is_ready(priv)) { + if (!iwl4965_is_ready(priv)) { IWL_WARNING("request scan called when driver not ready.\n"); goto done; } @@ -6906,7 +7073,7 @@ static void iwl_bg_request_scan(struct work_struct *data) goto done; } - if (iwl_is_rfkill(priv)) { + if (iwl4965_is_rfkill(priv)) { IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); goto done; } @@ -6922,7 +7089,7 @@ static void iwl_bg_request_scan(struct work_struct *data) } if (!priv->scan) { - priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + + priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan) { rc = -ENOMEM; @@ -6930,12 +7097,12 @@ static void iwl_bg_request_scan(struct work_struct *data) } } scan = priv->scan; - memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); + memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE); scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl4965_is_associated(priv)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -6965,14 +7132,14 @@ static void iwl_bg_request_scan(struct work_struct *data) if (priv->one_direct_scan) { IWL_DEBUG_SCAN ("Kicking off one direct scan for '%s'\n", - iwl_escape_essid(priv->direct_ssid, + iwl4965_escape_essid(priv->direct_ssid, priv->direct_ssid_len)); scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->direct_ssid_len; memcpy(scan->direct_scan[0].ssid, priv->direct_ssid, priv->direct_ssid_len); direct_mask = 1; - } else if (!iwl_is_associated(priv) && priv->essid_len) { + } else if (!iwl4965_is_associated(priv) && priv->essid_len) { scan->direct_scan[0].id = WLAN_EID_SSID; scan->direct_scan[0].len = priv->essid_len; memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); @@ -6983,7 +7150,7 @@ static void iwl_bg_request_scan(struct work_struct *data) /* 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.len = cpu_to_le16( - iwl_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, + iwl4965_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data, IWL_MAX_SCAN_SIZE - sizeof(scan), 0)); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; scan->tx_cmd.sta_id = priv->hw_setting.bcast_sta_id; @@ -6997,7 +7164,7 @@ static void iwl_bg_request_scan(struct work_struct *data) case 2: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; scan->tx_cmd.rate_n_flags = - iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, + iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); scan->good_CRC_th = 0; @@ -7006,7 +7173,7 @@ static void iwl_bg_request_scan(struct work_struct *data) case 1: scan->tx_cmd.rate_n_flags = - iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, + iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, RATE_MCS_ANT_B_MSK); scan->good_CRC_th = IWL_GOOD_CRC_TH; phymode = MODE_IEEE80211A; @@ -7033,23 +7200,23 @@ static void iwl_bg_request_scan(struct work_struct *data) if (direct_mask) IWL_DEBUG_SCAN ("Initiating direct scan for %s.\n", - iwl_escape_essid(priv->essid, priv->essid_len)); + iwl4965_escape_essid(priv->essid, priv->essid_len)); else IWL_DEBUG_SCAN("Initiating indirect scan.\n"); scan->channel_count = - iwl_get_channels_for_scan( + iwl4965_get_channels_for_scan( priv, phymode, 1, /* active */ direct_mask, (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); cmd.len += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl_scan_channel); + scan->channel_count * sizeof(struct iwl4965_scan_channel); cmd.data = scan; scan->len = cpu_to_le16(cmd.len); set_bit(STATUS_SCAN_HW, &priv->status); - rc = iwl_send_cmd_sync(priv, &cmd); + rc = iwl4965_send_cmd_sync(priv, &cmd); if (rc) goto done; @@ -7060,50 +7227,52 @@ static void iwl_bg_request_scan(struct work_struct *data) return; done: - /* inform mac80211 sacn aborted */ + /* inform mac80211 scan aborted */ queue_work(priv->workqueue, &priv->scan_completed); mutex_unlock(&priv->mutex); } -static void iwl_bg_up(struct work_struct *data) +static void iwl4965_bg_up(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, up); + struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, up); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - __iwl_up(priv); + __iwl4965_up(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_restart(struct work_struct *data) +static void iwl4965_bg_restart(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); + struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, restart); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - iwl_down(priv); + iwl4965_down(priv); queue_work(priv->workqueue, &priv->up); } -static void iwl_bg_rx_replenish(struct work_struct *data) +static void iwl4965_bg_rx_replenish(struct work_struct *data) { - struct iwl_priv *priv = - container_of(data, struct iwl_priv, rx_replenish); + struct iwl4965_priv *priv = + container_of(data, struct iwl4965_priv, rx_replenish); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; mutex_lock(&priv->mutex); - iwl_rx_replenish(priv); + iwl4965_rx_replenish(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_post_associate(struct work_struct *data) +#define IWL_DELAY_NEXT_SCAN (HZ*2) + +static void iwl4965_bg_post_associate(struct work_struct *data) { - struct iwl_priv *priv = container_of(data, struct iwl_priv, + struct iwl4965_priv *priv = container_of(data, struct iwl4965_priv, post_associate.work); int rc = 0; @@ -7129,16 +7298,16 @@ static void iwl_bg_post_associate(struct work_struct *data) mutex_unlock(&priv->mutex); return; } - iwl_scan_cancel_timeout(priv, 200); + iwl4965_scan_cancel_timeout(priv, 200); conf = ieee80211_get_hw_conf(priv->hw); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd)); + iwl4965_setup_rxon_timing(priv); + rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON_TIMING, sizeof(priv->rxon_timing), &priv->rxon_timing); if (rc) IWL_WARNING("REPLY_RXON_TIMING failed - " @@ -7146,15 +7315,10 @@ static void iwl_bg_post_associate(struct work_struct *data) priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; -#ifdef CONFIG_IWLWIFI_HT - if (priv->is_ht_enabled && priv->current_assoc_ht.is_ht) - iwl4965_set_rxon_ht(priv, &priv->current_assoc_ht); - else { - priv->active_rate_ht[0] = 0; - priv->active_rate_ht[1] = 0; - priv->current_channel_width = IWL_CHANNEL_WIDTH_20MHZ; - } -#endif /* CONFIG_IWLWIFI_HT*/ +#ifdef CONFIG_IWL4965_HT + if (priv->current_ht_config.is_ht) + iwl4965_set_rxon_ht(priv, &priv->current_ht_config); +#endif /* CONFIG_IWL4965_HT*/ iwl4965_set_rxon_chain(priv); priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); @@ -7177,22 +7341,22 @@ static void iwl_bg_post_associate(struct work_struct *data) } - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); switch (priv->iw_mode) { case IEEE80211_IF_TYPE_STA: - iwl_rate_scale_init(priv->hw, IWL_AP_ID); + iwl4965_rate_scale_init(priv->hw, IWL_AP_ID); break; case IEEE80211_IF_TYPE_IBSS: /* clear out the station table */ - iwl_clear_stations_table(priv); + iwl4965_clear_stations_table(priv); - iwl_rxon_add_station(priv, BROADCAST_ADDR, 0); - iwl_rxon_add_station(priv, priv->bssid, 0); - iwl_rate_scale_init(priv->hw, IWL_STA_ID); - iwl_send_beacon_cmd(priv); + iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); + iwl4965_rxon_add_station(priv, priv->bssid, 0); + iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); + iwl4965_send_beacon_cmd(priv); break; @@ -7202,55 +7366,61 @@ static void iwl_bg_post_associate(struct work_struct *data) break; } - iwl_sequence_reset(priv); + iwl4965_sequence_reset(priv); -#ifdef CONFIG_IWLWIFI_SENSITIVITY +#ifdef CONFIG_IWL4965_SENSITIVITY /* Enable Rx differential gain and sensitivity calibrations */ iwl4965_chain_noise_reset(priv); priv->start_calib = 1; -#endif /* CONFIG_IWLWIFI_SENSITIVITY */ +#endif /* CONFIG_IWL4965_SENSITIVITY */ if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS) priv->assoc_station_added = 1; -#ifdef CONFIG_IWLWIFI_QOS - iwl_activate_qos(priv, 0); -#endif /* CONFIG_IWLWIFI_QOS */ +#ifdef CONFIG_IWL4965_QOS + iwl4965_activate_qos(priv, 0); +#endif /* CONFIG_IWL4965_QOS */ + /* we have just associated, don't start scan too early */ + priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; mutex_unlock(&priv->mutex); } -static void iwl_bg_abort_scan(struct work_struct *work) +static void iwl4965_bg_abort_scan(struct work_struct *work) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, - abort_scan); + struct iwl4965_priv *priv = container_of(work, struct iwl4965_priv, abort_scan); - if (!iwl_is_ready(priv)) + if (!iwl4965_is_ready(priv)) return; mutex_lock(&priv->mutex); set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); + iwl4965_send_scan_abort(priv); mutex_unlock(&priv->mutex); } -static void iwl_bg_scan_completed(struct work_struct *work) +static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); + +static void iwl4965_bg_scan_completed(struct work_struct *work) { - struct iwl_priv *priv = - container_of(work, struct iwl_priv, scan_completed); + struct iwl4965_priv *priv = + container_of(work, struct iwl4965_priv, scan_completed); IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n"); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; + if (priv->cache_conf) + iwl4965_mac_config(priv->hw, priv->cache_conf); + ieee80211_scan_completed(priv->hw); /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ mutex_lock(&priv->mutex); - iwl_hw_reg_send_txpower(priv); + iwl4965_hw_reg_send_txpower(priv); mutex_unlock(&priv->mutex); } @@ -7260,9 +7430,9 @@ static void iwl_bg_scan_completed(struct work_struct *work) * *****************************************************************************/ -static int iwl_mac_start(struct ieee80211_hw *hw) +static int iwl4965_mac_start(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -7271,7 +7441,7 @@ static int iwl_mac_start(struct ieee80211_hw *hw) priv->is_open = 1; - if (!iwl_is_rfkill(priv)) + if (!iwl4965_is_rfkill(priv)) ieee80211_start_queues(priv->hw); mutex_unlock(&priv->mutex); @@ -7279,9 +7449,9 @@ static int iwl_mac_start(struct ieee80211_hw *hw) return 0; } -static void iwl_mac_stop(struct ieee80211_hw *hw) +static void iwl4965_mac_stop(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -7291,19 +7461,25 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) * RXON_FILTER_ASSOC_MSK BIT */ priv->is_open = 0; - iwl_scan_cancel_timeout(priv, 100); + if (!iwl4965_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211("leave - RF not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + + iwl4965_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211("leave\n"); } -static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, +static int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *ctl) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); @@ -7315,17 +7491,17 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, ctl->tx_rate); - if (iwl_tx_skb(priv, skb, ctl)) + if (iwl4965_tx_skb(priv, skb, ctl)) dev_kfree_skb_any(skb); IWL_DEBUG_MAC80211("leave\n"); return 0; } -static int iwl_mac_add_interface(struct ieee80211_hw *hw, +static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; unsigned long flags; DECLARE_MAC_BUF(mac); @@ -7347,7 +7523,7 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211("Set %s\n", print_mac(mac, conf->mac_addr)); memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); } - iwl_set_mode(priv, conf->type); + iwl4965_set_mode(priv, conf->type); IWL_DEBUG_MAC80211("leave\n"); mutex_unlock(&priv->mutex); @@ -7356,49 +7532,64 @@ static int iwl_mac_add_interface(struct ieee80211_hw *hw, } /** - * iwl_mac_config - mac80211 config callback + * iwl4965_mac_config - mac80211 config callback * * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to * be set inappropriately and the driver currently sets the hardware up to * use it whenever needed. */ -static int iwl_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) +static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) { - struct iwl_priv *priv = hw->priv; - const struct iwl_channel_info *ch_info; + struct iwl4965_priv *priv = hw->priv; + const struct iwl4965_channel_info *ch_info; unsigned long flags; + int ret = 0; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter to channel %d\n", conf->channel); - if (!iwl_is_ready(priv)) { + if (!iwl4965_is_ready(priv)) { IWL_DEBUG_MAC80211("leave - not ready\n"); - mutex_unlock(&priv->mutex); - return -EIO; + ret = -EIO; + goto out; } /* TODO: Figure out how to get ieee80211_local->sta_scanning w/ only - * what is exposed through include/ declrations */ - if (unlikely(!iwl_param_disable_hw_scan && + * what is exposed through include/ declarations */ + if (unlikely(!iwl4965_param_disable_hw_scan && test_bit(STATUS_SCANNING, &priv->status))) { - IWL_DEBUG_MAC80211("leave - scanning\n"); + + if (unlikely(priv->cache_conf)) + IWL_DEBUG_MAC80211("leave - still scanning\n"); + else { + /* Cache the configuration now so that we can + * replay it after the hardware scan is finished. */ + priv->cache_conf = kmalloc(sizeof(*conf), GFP_KERNEL); + if (priv->cache_conf) { + memcpy(priv->cache_conf, conf, sizeof(*conf)); + IWL_DEBUG_MAC80211("leave - scanning\n"); + } else { + IWL_DEBUG_MAC80211("leave - no memory\n"); + ret = -ENOMEM; + } + } mutex_unlock(&priv->mutex); - return 0; + return ret; } spin_lock_irqsave(&priv->lock, flags); - ch_info = iwl_get_channel_info(priv, conf->phymode, conf->channel); + ch_info = iwl4965_get_channel_info(priv, conf->phymode, conf->channel); if (!is_channel_valid(ch_info)) { IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", conf->channel, conf->phymode); IWL_DEBUG_MAC80211("leave - invalid channel\n"); spin_unlock_irqrestore(&priv->lock, flags); - mutex_unlock(&priv->mutex); - return -EINVAL; + ret = -EINVAL; + goto out; } -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT /* if we are switching fron ht to 2.4 clear flags * from any ht related info since 2.4 does not * support ht */ @@ -7408,57 +7599,59 @@ static int iwl_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) #endif ) priv->staging_rxon.flags = 0; -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT */ - iwl_set_rxon_channel(priv, conf->phymode, conf->channel); + iwl4965_set_rxon_channel(priv, conf->phymode, conf->channel); - iwl_set_flags_for_phymode(priv, conf->phymode); + iwl4965_set_flags_for_phymode(priv, conf->phymode); /* The list of supported rates and rate mask can be different * for each phymode; since the phymode may have changed, reset * the rate mask to what mac80211 lists */ - iwl_set_rate(priv); + iwl4965_set_rate(priv); spin_unlock_irqrestore(&priv->lock, flags); #ifdef IEEE80211_CONF_CHANNEL_SWITCH if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) { - iwl_hw_channel_switch(priv, conf->channel); - mutex_unlock(&priv->mutex); - return 0; + iwl4965_hw_channel_switch(priv, conf->channel); + goto out; } #endif - iwl_radio_kill_sw(priv, !conf->radio_enabled); + iwl4965_radio_kill_sw(priv, !conf->radio_enabled); if (!conf->radio_enabled) { IWL_DEBUG_MAC80211("leave - radio disabled\n"); - mutex_unlock(&priv->mutex); - return 0; + goto out; } - if (iwl_is_rfkill(priv)) { + if (iwl4965_is_rfkill(priv)) { IWL_DEBUG_MAC80211("leave - RF kill\n"); - mutex_unlock(&priv->mutex); - return -EIO; + ret = -EIO; + goto out; } - iwl_set_rate(priv); + iwl4965_set_rate(priv); if (memcmp(&priv->active_rxon, &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); else IWL_DEBUG_INFO("No re-sending same RXON configuration.\n"); IWL_DEBUG_MAC80211("leave\n"); +out: + if (priv->cache_conf) { + kfree(priv->cache_conf); + priv->cache_conf = NULL; + } mutex_unlock(&priv->mutex); - - return 0; + return ret; } -static void iwl_config_ap(struct iwl_priv *priv) +static void iwl4965_config_ap(struct iwl4965_priv *priv) { int rc = 0; @@ -7470,12 +7663,12 @@ static void iwl_config_ap(struct iwl_priv *priv) /* RXON - unassoc (to set timing command) */ priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); /* RXON Timing */ - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, + memset(&priv->rxon_timing, 0, sizeof(struct iwl4965_rxon_time_cmd)); + iwl4965_setup_rxon_timing(priv); + rc = iwl4965_send_cmd_pdu(priv, REPLY_RXON_TIMING, sizeof(priv->rxon_timing), &priv->rxon_timing); if (rc) IWL_WARNING("REPLY_RXON_TIMING failed - " @@ -7507,23 +7700,23 @@ static void iwl_config_ap(struct iwl_priv *priv) } /* restore RXON assoc */ priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); -#ifdef CONFIG_IWLWIFI_QOS - iwl_activate_qos(priv, 1); + iwl4965_commit_rxon(priv); +#ifdef CONFIG_IWL4965_QOS + iwl4965_activate_qos(priv, 1); #endif - iwl_rxon_add_station(priv, BROADCAST_ADDR, 0); + iwl4965_rxon_add_station(priv, iwl4965_broadcast_addr, 0); } - iwl_send_beacon_cmd(priv); + iwl4965_send_beacon_cmd(priv); /* FIXME - we need to add code here to detect a totally new * configuration, reset the AP, unassoc, rxon timing, assoc, * clear sta table, add BCAST sta... */ } -static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, +static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, int if_id, struct ieee80211_if_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; DECLARE_MAC_BUF(mac); unsigned long flags; int rc; @@ -7576,11 +7769,14 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, priv->ibss_beacon = conf->beacon; } + if (iwl4965_is_rfkill(priv)) + goto done; + if (conf->bssid && !is_zero_ether_addr(conf->bssid) && !is_multicast_ether_addr(conf->bssid)) { /* If there is currently a HW scan going on in the background * then we need to cancel it else the RXON below will fail. */ - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl4965_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress " "after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); @@ -7596,20 +7792,21 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, memcpy(priv->bssid, conf->bssid, ETH_ALEN); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) - iwl_config_ap(priv); + iwl4965_config_ap(priv); else { - rc = iwl_commit_rxon(priv); + rc = iwl4965_commit_rxon(priv); if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc) - iwl_rxon_add_station( + iwl4965_rxon_add_station( priv, priv->active_rxon.bssid_addr, 1); } } else { - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); } + done: spin_lock_irqsave(&priv->lock, flags); if (!conf->ssid_len) memset(priv->essid, 0, IW_ESSID_MAX_SIZE); @@ -7625,32 +7822,33 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id, return 0; } -static void iwl_configure_filter(struct ieee80211_hw *hw, +static void iwl4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, int mc_count, struct dev_addr_list *mc_list) { /* * XXX: dummy - * see also iwl_connection_init_rx_config + * see also iwl4965_connection_init_rx_config */ *total_flags = 0; } -static void iwl_mac_remove_interface(struct ieee80211_hw *hw, +static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - cancel_delayed_work(&priv->post_associate); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); - + if (iwl4965_is_ready_rf(priv)) { + iwl4965_scan_cancel_timeout(priv, 100); + cancel_delayed_work(&priv->post_associate); + priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl4965_commit_rxon(priv); + } if (priv->interface_id == conf->if_id) { priv->interface_id = 0; memset(priv->bssid, 0, ETH_ALEN); @@ -7662,20 +7860,41 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211("leave\n"); } +static void iwl4965_mac_erp_ie_changed(struct ieee80211_hw *hw, + u8 changes, int cts_protection, int preamble) +{ + struct iwl4965_priv *priv = hw->priv; -#define IWL_DELAY_NEXT_SCAN (HZ*2) -static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) + if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) { + if (preamble == WLAN_ERP_PREAMBLE_SHORT) + priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + else + priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + } + + if (changes & IEEE80211_ERP_CHANGE_PROTECTION) { + if (cts_protection && (priv->phymode != MODE_IEEE80211A)) + priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; + else + priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + } + + if (iwl4965_is_associated(priv)) + iwl4965_send_rxon_assoc(priv); +} + +static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) { int rc = 0; unsigned long flags; - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter\n"); mutex_lock(&priv->mutex); spin_lock_irqsave(&priv->lock, flags); - if (!iwl_is_ready_rf(priv)) { + if (!iwl4965_is_ready_rf(priv)) { rc = -EIO; IWL_DEBUG_MAC80211("leave - not ready or exit pending\n"); goto out_unlock; @@ -7687,17 +7906,21 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) goto out_unlock; } + /* we don't schedule scan within next_scan_jiffies period */ + if (priv->next_scan_jiffies && + time_after(priv->next_scan_jiffies, jiffies)) { + rc = -EAGAIN; + goto out_unlock; + } /* if we just finished scan ask for delay */ - if (priv->last_scan_jiffies && - time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, - jiffies)) { + if (priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + + IWL_DELAY_NEXT_SCAN, jiffies)) { rc = -EAGAIN; goto out_unlock; } if (len) { - IWL_DEBUG_SCAN("direct scan for " - "%s [%d]\n ", - iwl_escape_essid(ssid, len), (int)len); + IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", + iwl4965_escape_essid(ssid, len), (int)len); priv->one_direct_scan = 1; priv->direct_ssid_len = (u8) @@ -7706,7 +7929,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) } else priv->one_direct_scan = 0; - rc = iwl_scan_initiate(priv); + rc = iwl4965_scan_initiate(priv); IWL_DEBUG_MAC80211("leave\n"); @@ -7717,18 +7940,18 @@ out_unlock: return rc; } -static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, +static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, const u8 *local_addr, const u8 *addr, struct ieee80211_key_conf *key) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; DECLARE_MAC_BUF(mac); int rc = 0; u8 sta_id; IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_param_hwcrypto) { + if (!iwl4965_param_hwcrypto) { IWL_DEBUG_MAC80211("leave - hwcrypto disabled\n"); return -EOPNOTSUPP; } @@ -7737,7 +7960,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, /* only support pairwise keys */ return -EOPNOTSUPP; - sta_id = iwl_hw_find_station(priv, addr); + sta_id = iwl4965_hw_find_station(priv, addr); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_MAC80211("leave - %s not in station map.\n", print_mac(mac, addr)); @@ -7746,24 +7969,24 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); switch (cmd) { case SET_KEY: - rc = iwl_update_sta_key_info(priv, key, sta_id); + rc = iwl4965_update_sta_key_info(priv, key, sta_id); if (!rc) { - iwl_set_rxon_hwcrypto(priv, 1); - iwl_commit_rxon(priv); + iwl4965_set_rxon_hwcrypto(priv, 1); + iwl4965_commit_rxon(priv); key->hw_key_idx = sta_id; IWL_DEBUG_MAC80211("set_key success, using hwcrypto\n"); key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; } break; case DISABLE_KEY: - rc = iwl_clear_sta_key_info(priv, sta_id); + rc = iwl4965_clear_sta_key_info(priv, sta_id); if (!rc) { - iwl_set_rxon_hwcrypto(priv, 0); - iwl_commit_rxon(priv); + iwl4965_set_rxon_hwcrypto(priv, 0); + iwl4965_commit_rxon(priv); IWL_DEBUG_MAC80211("disable hwcrypto key\n"); } break; @@ -7777,18 +8000,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return rc; } -static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, +static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, int queue, const struct ieee80211_tx_queue_params *params) { - struct iwl_priv *priv = hw->priv; -#ifdef CONFIG_IWLWIFI_QOS + struct iwl4965_priv *priv = hw->priv; +#ifdef CONFIG_IWL4965_QOS unsigned long flags; int q; -#endif /* CONFIG_IWL_QOS */ +#endif /* CONFIG_IWL4965_QOS */ IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl4965_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); return -EIO; } @@ -7798,7 +8021,7 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, return 0; } -#ifdef CONFIG_IWLWIFI_QOS +#ifdef CONFIG_IWL4965_QOS if (!priv->qos_data.qos_enable) { priv->qos_data.qos_active = 0; IWL_DEBUG_MAC80211("leave - qos not enabled\n"); @@ -7821,30 +8044,30 @@ static int iwl_mac_conf_tx(struct ieee80211_hw *hw, int queue, mutex_lock(&priv->mutex); if (priv->iw_mode == IEEE80211_IF_TYPE_AP) - iwl_activate_qos(priv, 1); - else if (priv->assoc_id && iwl_is_associated(priv)) - iwl_activate_qos(priv, 0); + iwl4965_activate_qos(priv, 1); + else if (priv->assoc_id && iwl4965_is_associated(priv)) + iwl4965_activate_qos(priv, 0); mutex_unlock(&priv->mutex); -#endif /*CONFIG_IWLWIFI_QOS */ +#endif /*CONFIG_IWL4965_QOS */ IWL_DEBUG_MAC80211("leave\n"); return 0; } -static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, +static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw, struct ieee80211_tx_queue_stats *stats) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; int i, avail; - struct iwl_tx_queue *txq; - struct iwl_queue *q; + struct iwl4965_tx_queue *txq; + struct iwl4965_queue *q; unsigned long flags; IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl4965_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); return -EIO; } @@ -7854,7 +8077,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, for (i = 0; i < AC_NUM; i++) { txq = &priv->txq[i]; q = &txq->q; - avail = iwl_queue_space(q); + avail = iwl4965_queue_space(q); stats->data[i].len = q->n_window - avail; stats->data[i].limit = q->n_window - q->high_mark; @@ -7868,7 +8091,7 @@ static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw, return 0; } -static int iwl_mac_get_stats(struct ieee80211_hw *hw, +static int iwl4965_mac_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { IWL_DEBUG_MAC80211("enter\n"); @@ -7877,7 +8100,7 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw, return 0; } -static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw) +static u64 iwl4965_mac_get_tsf(struct ieee80211_hw *hw) { IWL_DEBUG_MAC80211("enter\n"); IWL_DEBUG_MAC80211("leave\n"); @@ -7885,35 +8108,35 @@ static u64 iwl_mac_get_tsf(struct ieee80211_hw *hw) return 0; } -static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) +static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; unsigned long flags; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); priv->lq_mngr.lq_ready = 0; -#ifdef CONFIG_IWLWIFI_HT +#ifdef CONFIG_IWL4965_HT spin_lock_irqsave(&priv->lock, flags); - memset(&priv->current_assoc_ht, 0, sizeof(struct sta_ht_info)); + memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); spin_unlock_irqrestore(&priv->lock, flags); -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT_AGG /* if (priv->lq_mngr.agg_ctrl.granted_ba) iwl4965_turn_off_agg(priv, TID_ALL_SPECIFIED);*/ - memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl_agg_control)); + memset(&(priv->lq_mngr.agg_ctrl), 0, sizeof(struct iwl4965_agg_control)); priv->lq_mngr.agg_ctrl.tid_traffic_load_threshold = 10; priv->lq_mngr.agg_ctrl.ba_timeout = 5000; priv->lq_mngr.agg_ctrl.auto_agg = 1; if (priv->lq_mngr.agg_ctrl.auto_agg) priv->lq_mngr.agg_ctrl.requested_ba = TID_ALL_ENABLED; -#endif /*CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /*CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ -#ifdef CONFIG_IWLWIFI_QOS - iwl_reset_qos(priv); +#ifdef CONFIG_IWL4965_QOS + iwl4965_reset_qos(priv); #endif cancel_delayed_work(&priv->post_associate); @@ -7938,13 +8161,19 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->lock, flags); + if (!iwl4965_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211("leave - not ready\n"); + mutex_unlock(&priv->mutex); + return; + } + /* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); } /* Per mac80211.h: This is only used in IBSS mode... */ @@ -7955,15 +8184,9 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) return; } - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211("leave - not ready\n"); - mutex_unlock(&priv->mutex); - return; - } - priv->only_active_channel = 0; - iwl_set_rate(priv); + iwl4965_set_rate(priv); mutex_unlock(&priv->mutex); @@ -7971,16 +8194,16 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw) } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, +static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { - struct iwl_priv *priv = hw->priv; + struct iwl4965_priv *priv = hw->priv; unsigned long flags; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211("enter\n"); - if (!iwl_is_ready_rf(priv)) { + if (!iwl4965_is_ready_rf(priv)) { IWL_DEBUG_MAC80211("leave - RF not ready\n"); mutex_unlock(&priv->mutex); return -EIO; @@ -8004,8 +8227,8 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, IWL_DEBUG_MAC80211("leave\n"); spin_unlock_irqrestore(&priv->lock, flags); -#ifdef CONFIG_IWLWIFI_QOS - iwl_reset_qos(priv); +#ifdef CONFIG_IWL4965_QOS + iwl4965_reset_qos(priv); #endif queue_work(priv->workqueue, &priv->post_associate.work); @@ -8015,133 +8238,62 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, return 0; } -#ifdef CONFIG_IWLWIFI_HT -union ht_cap_info { - struct { - u16 advanced_coding_cap :1; - u16 supported_chan_width_set :1; - u16 mimo_power_save_mode :2; - u16 green_field :1; - u16 short_GI20 :1; - u16 short_GI40 :1; - u16 tx_stbc :1; - u16 rx_stbc :1; - u16 beam_forming :1; - u16 delayed_ba :1; - u16 maximal_amsdu_size :1; - u16 cck_mode_at_40MHz :1; - u16 psmp_support :1; - u16 stbc_ctrl_frame_support :1; - u16 sig_txop_protection_support :1; - }; - u16 val; -} __attribute__ ((packed)); - -union ht_param_info{ - struct { - u8 max_rx_ampdu_factor :2; - u8 mpdu_density :3; - u8 reserved :3; - }; - u8 val; -} __attribute__ ((packed)); - -union ht_exra_param_info { - struct { - u8 ext_chan_offset :2; - u8 tx_chan_width :1; - u8 rifs_mode :1; - u8 controlled_access_only :1; - u8 service_interval_granularity :3; - }; - u8 val; -} __attribute__ ((packed)); - -union ht_operation_mode{ - struct { - u16 op_mode :2; - u16 non_GF :1; - u16 reserved :13; - }; - u16 val; -} __attribute__ ((packed)); +#ifdef CONFIG_IWL4965_HT - -static int sta_ht_info_init(struct ieee80211_ht_capability *ht_cap, - struct ieee80211_ht_additional_info *ht_extra, - struct sta_ht_info *ht_info_ap, - struct sta_ht_info *ht_info) +static void iwl4965_ht_info_fill(struct ieee80211_conf *conf, + struct iwl4965_priv *priv) { - union ht_cap_info cap; - union ht_operation_mode op_mode; - union ht_param_info param_info; - union ht_exra_param_info extra_param_info; + struct iwl_ht_info *iwl_conf = &priv->current_ht_config; + struct ieee80211_ht_info *ht_conf = &conf->ht_conf; + struct ieee80211_ht_bss_info *ht_bss_conf = &conf->ht_bss_conf; IWL_DEBUG_MAC80211("enter: \n"); - if (!ht_info) { - IWL_DEBUG_MAC80211("leave: ht_info is NULL\n"); - return -1; + if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) { + iwl_conf->is_ht = 0; + return; } - if (ht_cap) { - cap.val = (u16) le16_to_cpu(ht_cap->capabilities_info); - param_info.val = ht_cap->mac_ht_params_info; - ht_info->is_ht = 1; - if (cap.short_GI20) - ht_info->sgf |= 0x1; - if (cap.short_GI40) - ht_info->sgf |= 0x2; - ht_info->is_green_field = cap.green_field; - ht_info->max_amsdu_size = cap.maximal_amsdu_size; - ht_info->supported_chan_width = cap.supported_chan_width_set; - ht_info->tx_mimo_ps_mode = cap.mimo_power_save_mode; - memcpy(ht_info->supp_rates, ht_cap->supported_mcs_set, 16); - - ht_info->ampdu_factor = param_info.max_rx_ampdu_factor; - ht_info->mpdu_density = param_info.mpdu_density; - - IWL_DEBUG_MAC80211("SISO mask 0x%X MIMO mask 0x%X \n", - ht_cap->supported_mcs_set[0], - ht_cap->supported_mcs_set[1]); - - if (ht_info_ap) { - ht_info->control_channel = ht_info_ap->control_channel; - ht_info->extension_chan_offset = - ht_info_ap->extension_chan_offset; - ht_info->tx_chan_width = ht_info_ap->tx_chan_width; - ht_info->operating_mode = ht_info_ap->operating_mode; - } - - if (ht_extra) { - extra_param_info.val = ht_extra->ht_param; - ht_info->control_channel = ht_extra->control_chan; - ht_info->extension_chan_offset = - extra_param_info.ext_chan_offset; - ht_info->tx_chan_width = extra_param_info.tx_chan_width; - op_mode.val = (u16) - le16_to_cpu(ht_extra->operation_mode); - ht_info->operating_mode = op_mode.op_mode; - IWL_DEBUG_MAC80211("control channel %d\n", - ht_extra->control_chan); - } - } else - ht_info->is_ht = 0; - + iwl_conf->is_ht = 1; + priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); + + if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) + iwl_conf->sgf |= 0x1; + if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) + iwl_conf->sgf |= 0x2; + + iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); + iwl_conf->max_amsdu_size = + !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); + iwl_conf->supported_chan_width = + !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); + iwl_conf->tx_mimo_ps_mode = + (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); + memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); + + iwl_conf->control_channel = ht_bss_conf->primary_channel; + iwl_conf->extension_chan_offset = + ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; + iwl_conf->tx_chan_width = + !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); + iwl_conf->ht_protection = + ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; + iwl_conf->non_GF_STA_present = + !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); + + IWL_DEBUG_MAC80211("control channel %d\n", + iwl_conf->control_channel); IWL_DEBUG_MAC80211("leave\n"); - return 0; } -static int iwl_mac_conf_ht(struct ieee80211_hw *hw, - struct ieee80211_ht_capability *ht_cap, - struct ieee80211_ht_additional_info *ht_extra) +static int iwl4965_mac_conf_ht(struct ieee80211_hw *hw, + struct ieee80211_conf *conf) { - struct iwl_priv *priv = hw->priv; - int rs; + struct iwl4965_priv *priv = hw->priv; IWL_DEBUG_MAC80211("enter: \n"); - rs = sta_ht_info_init(ht_cap, ht_extra, NULL, &priv->current_assoc_ht); + iwl4965_ht_info_fill(conf, priv); iwl4965_set_rxon_chain(priv); if (priv && priv->assoc_id && @@ -8156,58 +8308,33 @@ static int iwl_mac_conf_ht(struct ieee80211_hw *hw, spin_unlock_irqrestore(&priv->lock, flags); } - IWL_DEBUG_MAC80211("leave: control channel %d\n", - ht_extra->control_chan); - return rs; - + IWL_DEBUG_MAC80211("leave:\n"); + return 0; } -static void iwl_set_ht_capab(struct ieee80211_hw *hw, - struct ieee80211_ht_capability *ht_cap, - u8 use_wide_chan) +static void iwl4965_set_ht_capab(struct ieee80211_hw *hw, + struct ieee80211_ht_cap *ht_cap, + u8 use_current_config) { - union ht_cap_info cap; - union ht_param_info param_info; + struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_hw_mode *mode = conf->mode; - memset(&cap, 0, sizeof(union ht_cap_info)); - memset(¶m_info, 0, sizeof(union ht_param_info)); - - cap.maximal_amsdu_size = HT_IE_MAX_AMSDU_SIZE_4K; - cap.green_field = 1; - cap.short_GI20 = 1; - cap.short_GI40 = 1; - cap.supported_chan_width_set = use_wide_chan; - cap.mimo_power_save_mode = 0x3; - - param_info.max_rx_ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; - param_info.mpdu_density = CFG_HT_MPDU_DENSITY_DEF; - ht_cap->capabilities_info = (__le16) cpu_to_le16(cap.val); - ht_cap->mac_ht_params_info = (u8) param_info.val; - - ht_cap->supported_mcs_set[0] = 0xff; - ht_cap->supported_mcs_set[1] = 0xff; - ht_cap->supported_mcs_set[4] = - (cap.supported_chan_width_set) ? 0x1: 0x0; + if (use_current_config) { + ht_cap->cap_info = cpu_to_le16(conf->ht_conf.cap); + memcpy(ht_cap->supp_mcs_set, + conf->ht_conf.supp_mcs_set, 16); + } else { + ht_cap->cap_info = cpu_to_le16(mode->ht_info.cap); + memcpy(ht_cap->supp_mcs_set, + mode->ht_info.supp_mcs_set, 16); + } + ht_cap->ampdu_params_info = + (mode->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | + ((mode->ht_info.ampdu_density << 2) & + IEEE80211_HT_CAP_AMPDU_DENSITY); } -static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw, - struct ieee80211_ht_capability *ht_cap) -{ - u8 use_wide_channel = 1; - struct iwl_priv *priv = hw->priv; - - IWL_DEBUG_MAC80211("enter: \n"); - if (priv->channel_width != IWL_CHANNEL_WIDTH_40MHZ) - use_wide_channel = 0; - - /* no fat tx allowed on 2.4GHZ */ - if (priv->phymode != MODE_IEEE80211A) - use_wide_channel = 0; - - iwl_set_ht_capab(hw, ht_cap, use_wide_channel); - IWL_DEBUG_MAC80211("leave: \n"); -} -#endif /*CONFIG_IWLWIFI_HT*/ +#endif /*CONFIG_IWL4965_HT*/ /***************************************************************************** * @@ -8215,7 +8342,7 @@ static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw, * *****************************************************************************/ -#ifdef CONFIG_IWLWIFI_DEBUG +#ifdef CONFIG_IWL4965_DEBUG /* * The following adds a new attribute to the sysfs representation @@ -8227,7 +8354,7 @@ static void iwl_mac_get_ht_capab(struct ieee80211_hw *hw, static ssize_t show_debug_level(struct device_driver *d, char *buf) { - return sprintf(buf, "0x%08X\n", iwl_debug_level); + return sprintf(buf, "0x%08X\n", iwl4965_debug_level); } static ssize_t store_debug_level(struct device_driver *d, const char *buf, size_t count) @@ -8240,7 +8367,7 @@ static ssize_t store_debug_level(struct device_driver *d, printk(KERN_INFO DRV_NAME ": %s is not in hex or decimal form.\n", buf); else - iwl_debug_level = val; + iwl4965_debug_level = val; return strnlen(buf, count); } @@ -8248,7 +8375,7 @@ static ssize_t store_debug_level(struct device_driver *d, static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level, store_debug_level); -#endif /* CONFIG_IWLWIFI_DEBUG */ +#endif /* CONFIG_IWL4965_DEBUG */ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr, char *buf) @@ -8259,7 +8386,7 @@ static ssize_t show_rf_kill(struct device *d, * 2 - HW based RF kill active * 3 - Both HW and SW based RF kill active */ - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; int val = (test_bit(STATUS_RF_KILL_SW, &priv->status) ? 0x1 : 0x0) | (test_bit(STATUS_RF_KILL_HW, &priv->status) ? 0x2 : 0x0); @@ -8270,10 +8397,10 @@ static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; mutex_lock(&priv->mutex); - iwl_radio_kill_sw(priv, buf[0] == '1'); + iwl4965_radio_kill_sw(priv, buf[0] == '1'); mutex_unlock(&priv->mutex); return count; @@ -8284,12 +8411,12 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill); static ssize_t show_temperature(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; - if (!iwl_is_alive(priv)) + if (!iwl4965_is_alive(priv)) return -EAGAIN; - return sprintf(buf, "%d\n", iwl_hw_get_temperature(priv)); + return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv)); } static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); @@ -8298,15 +8425,15 @@ static ssize_t show_rs_window(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = d->driver_data; - return iwl_fill_rs_info(priv->hw, buf, IWL_AP_ID); + struct iwl4965_priv *priv = d->driver_data; + return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID); } static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL); static ssize_t show_tx_power(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; return sprintf(buf, "%d\n", priv->user_txpower_limit); } @@ -8314,7 +8441,7 @@ static ssize_t store_tx_power(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; char *p = (char *)buf; u32 val; @@ -8323,7 +8450,7 @@ static ssize_t store_tx_power(struct device *d, printk(KERN_INFO DRV_NAME ": %s is not in decimal form.\n", buf); else - iwl_hw_reg_set_txpower(priv, val); + iwl4965_hw_reg_set_txpower(priv, val); return count; } @@ -8333,7 +8460,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power); static ssize_t show_flags(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); } @@ -8342,19 +8469,19 @@ static ssize_t store_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; u32 flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.flags) != flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl4965_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", flags); priv->staging_rxon.flags = cpu_to_le32(flags); - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -8367,7 +8494,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags); static ssize_t show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.filter_flags)); @@ -8377,20 +8504,20 @@ static ssize_t store_filter_flags(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl4965_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.filter_flags = " "0x%04X\n", filter_flags); priv->staging_rxon.filter_flags = cpu_to_le32(filter_flags); - iwl_commit_rxon(priv); + iwl4965_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -8404,20 +8531,20 @@ static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags, static ssize_t show_tune(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; return sprintf(buf, "0x%04X\n", (priv->phymode << 8) | le16_to_cpu(priv->active_rxon.channel)); } -static void iwl_set_flags_for_phymode(struct iwl_priv *priv, u8 phymode); +static void iwl4965_set_flags_for_phymode(struct iwl4965_priv *priv, u8 phymode); static ssize_t store_tune(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; char *p = (char *)buf; u16 tune = simple_strtoul(p, &p, 0); u8 phymode = (tune >> 8) & 0xff; @@ -8428,9 +8555,9 @@ static ssize_t store_tune(struct device *d, mutex_lock(&priv->mutex); if ((le16_to_cpu(priv->staging_rxon.channel) != channel) || (priv->phymode != phymode)) { - const struct iwl_channel_info *ch_info; + const struct iwl4965_channel_info *ch_info; - ch_info = iwl_get_channel_info(priv, phymode, channel); + ch_info = iwl4965_get_channel_info(priv, phymode, channel); if (!ch_info) { IWL_WARNING("Requested invalid phymode/channel " "combination: %d %d\n", phymode, channel); @@ -8439,18 +8566,18 @@ static ssize_t store_tune(struct device *d, } /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl4965_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing phymode and " "rxon.channel = %d %d\n", phymode, channel); - iwl_set_rxon_channel(priv, phymode, channel); - iwl_set_flags_for_phymode(priv, phymode); + iwl4965_set_rxon_channel(priv, phymode, channel); + iwl4965_set_flags_for_phymode(priv, phymode); - iwl_set_rate(priv); - iwl_commit_rxon(priv); + iwl4965_set_rate(priv); + iwl4965_commit_rxon(priv); } } mutex_unlock(&priv->mutex); @@ -8460,13 +8587,13 @@ static ssize_t store_tune(struct device *d, static DEVICE_ATTR(tune, S_IWUSR | S_IRUGO, show_tune, store_tune); -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT static ssize_t show_measurement(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); - struct iwl_spectrum_notification measure_report; + struct iwl4965_priv *priv = dev_get_drvdata(d); + struct iwl4965_spectrum_notification measure_report; u32 size = sizeof(measure_report), len = 0, ofs = 0; u8 *data = (u8 *) & measure_report; unsigned long flags; @@ -8498,7 +8625,7 @@ static ssize_t store_measurement(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); struct ieee80211_measurement_params params = { .channel = le16_to_cpu(priv->active_rxon.channel), .start_time = cpu_to_le64(priv->last_tsf), @@ -8524,20 +8651,20 @@ static ssize_t store_measurement(struct device *d, IWL_DEBUG_INFO("Invoking measurement of type %d on " "channel %d (for '%s')\n", type, params.channel, buf); - iwl_get_measurement(priv, ¶ms, type); + iwl4965_get_measurement(priv, ¶ms, type); return count; } static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR, show_measurement, store_measurement); -#endif /* CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT */ +#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */ static ssize_t store_retry_rate(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); priv->retry_rate = simple_strtoul(buf, NULL, 0); if (priv->retry_rate <= 0) @@ -8549,7 +8676,7 @@ static ssize_t store_retry_rate(struct device *d, static ssize_t show_retry_rate(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); return sprintf(buf, "%d", priv->retry_rate); } @@ -8560,14 +8687,14 @@ static ssize_t store_power_level(struct device *d, struct device_attribute *attr, const char *buf, size_t count) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); int rc; int mode; mode = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); - if (!iwl_is_ready(priv)) { + if (!iwl4965_is_ready(priv)) { rc = -EAGAIN; goto out; } @@ -8578,7 +8705,7 @@ static ssize_t store_power_level(struct device *d, mode |= IWL_POWER_ENABLED; if (mode != priv->power_mode) { - rc = iwl_send_power_mode(priv, IWL_POWER_LEVEL(mode)); + rc = iwl4965_send_power_mode(priv, IWL_POWER_LEVEL(mode)); if (rc) { IWL_DEBUG_MAC80211("failed setting power mode.\n"); goto out; @@ -8614,7 +8741,7 @@ static const s32 period_duration[] = { static ssize_t show_power_level(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); int level = IWL_POWER_LEVEL(priv->power_mode); char *p = buf; @@ -8649,18 +8776,18 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, static ssize_t show_channels(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); int len = 0, i; struct ieee80211_channel *channels = NULL; const struct ieee80211_hw_mode *hw_mode = NULL; int count = 0; - if (!iwl_is_ready(priv)) + if (!iwl4965_is_ready(priv)) return -EAGAIN; - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211G); + hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211G); if (!hw_mode) - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211B); + hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211B); if (hw_mode) { channels = hw_mode->channels; count = hw_mode->num_channels; @@ -8687,7 +8814,7 @@ static ssize_t show_channels(struct device *d, flag & IEEE80211_CHAN_W_ACTIVE_SCAN ? "active/passive" : "passive only"); - hw_mode = iwl_get_hw_mode(priv, MODE_IEEE80211A); + hw_mode = iwl4965_get_hw_mode(priv, MODE_IEEE80211A); if (hw_mode) { channels = hw_mode->channels; count = hw_mode->num_channels; @@ -8723,17 +8850,17 @@ static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); static ssize_t show_statistics(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); - u32 size = sizeof(struct iwl_notif_statistics); + struct iwl4965_priv *priv = dev_get_drvdata(d); + u32 size = sizeof(struct iwl4965_notif_statistics); u32 len = 0, ofs = 0; u8 *data = (u8 *) & priv->statistics; int rc = 0; - if (!iwl_is_alive(priv)) + if (!iwl4965_is_alive(priv)) return -EAGAIN; mutex_lock(&priv->mutex); - rc = iwl_send_statistics_request(priv); + rc = iwl4965_send_statistics_request(priv); mutex_unlock(&priv->mutex); if (rc) { @@ -8761,9 +8888,9 @@ static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); static ssize_t show_antenna(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); - if (!iwl_is_alive(priv)) + if (!iwl4965_is_alive(priv)) return -EAGAIN; return sprintf(buf, "%d\n", priv->antenna); @@ -8774,7 +8901,7 @@ static ssize_t store_antenna(struct device *d, const char *buf, size_t count) { int ant; - struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl4965_priv *priv = dev_get_drvdata(d); if (count == 0) return 0; @@ -8786,7 +8913,7 @@ static ssize_t store_antenna(struct device *d, if ((ant >= 0) && (ant <= 2)) { IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant); - priv->antenna = (enum iwl_antenna)ant; + priv->antenna = (enum iwl4965_antenna)ant; } else IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant); @@ -8799,8 +8926,8 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna); static ssize_t show_status(struct device *d, struct device_attribute *attr, char *buf) { - struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; - if (!iwl_is_alive(priv)) + struct iwl4965_priv *priv = (struct iwl4965_priv *)d->driver_data; + if (!iwl4965_is_alive(priv)) return -EAGAIN; return sprintf(buf, "0x%08x\n", (int)priv->status); } @@ -8814,7 +8941,7 @@ static ssize_t dump_error_log(struct device *d, char *p = (char *)buf; if (p[0] == '1') - iwl_dump_nic_error_log((struct iwl_priv *)d->driver_data); + iwl4965_dump_nic_error_log((struct iwl4965_priv *)d->driver_data); return strnlen(buf, count); } @@ -8828,7 +8955,7 @@ static ssize_t dump_event_log(struct device *d, char *p = (char *)buf; if (p[0] == '1') - iwl_dump_nic_event_log((struct iwl_priv *)d->driver_data); + iwl4965_dump_nic_event_log((struct iwl4965_priv *)d->driver_data); return strnlen(buf, count); } @@ -8841,34 +8968,34 @@ static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log); * *****************************************************************************/ -static void iwl_setup_deferred_work(struct iwl_priv *priv) +static void iwl4965_setup_deferred_work(struct iwl4965_priv *priv) { priv->workqueue = create_workqueue(DRV_NAME); init_waitqueue_head(&priv->wait_command_queue); - INIT_WORK(&priv->up, iwl_bg_up); - INIT_WORK(&priv->restart, iwl_bg_restart); - INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); - INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); - INIT_WORK(&priv->request_scan, iwl_bg_request_scan); - INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); - INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); - INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); - INIT_DELAYED_WORK(&priv->post_associate, iwl_bg_post_associate); - INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); - INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); - INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); - - iwl_hw_setup_deferred_work(priv); + INIT_WORK(&priv->up, iwl4965_bg_up); + INIT_WORK(&priv->restart, iwl4965_bg_restart); + INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); + INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed); + INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan); + INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); + INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); + INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); + INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); + INIT_DELAYED_WORK(&priv->init_alive_start, iwl4965_bg_init_alive_start); + INIT_DELAYED_WORK(&priv->alive_start, iwl4965_bg_alive_start); + INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check); + + iwl4965_hw_setup_deferred_work(priv); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)priv); + iwl4965_irq_tasklet, (unsigned long)priv); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv) +static void iwl4965_cancel_deferred_work(struct iwl4965_priv *priv) { - iwl_hw_cancel_deferred_work(priv); + iwl4965_hw_cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); cancel_delayed_work(&priv->scan_check); @@ -8877,14 +9004,14 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) cancel_work_sync(&priv->beacon_update); } -static struct attribute *iwl_sysfs_entries[] = { +static struct attribute *iwl4965_sysfs_entries[] = { &dev_attr_antenna.attr, &dev_attr_channels.attr, &dev_attr_dump_errors.attr, &dev_attr_dump_events.attr, &dev_attr_flags.attr, &dev_attr_filter_flags.attr, -#ifdef CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT +#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT &dev_attr_measurement.attr, #endif &dev_attr_power_level.attr, @@ -8900,54 +9027,56 @@ static struct attribute *iwl_sysfs_entries[] = { NULL }; -static struct attribute_group iwl_attribute_group = { +static struct attribute_group iwl4965_attribute_group = { .name = NULL, /* put in device directory */ - .attrs = iwl_sysfs_entries, + .attrs = iwl4965_sysfs_entries, }; -static struct ieee80211_ops iwl_hw_ops = { - .tx = iwl_mac_tx, - .start = iwl_mac_start, - .stop = iwl_mac_stop, - .add_interface = iwl_mac_add_interface, - .remove_interface = iwl_mac_remove_interface, - .config = iwl_mac_config, - .config_interface = iwl_mac_config_interface, - .configure_filter = iwl_configure_filter, - .set_key = iwl_mac_set_key, - .get_stats = iwl_mac_get_stats, - .get_tx_stats = iwl_mac_get_tx_stats, - .conf_tx = iwl_mac_conf_tx, - .get_tsf = iwl_mac_get_tsf, - .reset_tsf = iwl_mac_reset_tsf, - .beacon_update = iwl_mac_beacon_update, -#ifdef CONFIG_IWLWIFI_HT - .conf_ht = iwl_mac_conf_ht, - .get_ht_capab = iwl_mac_get_ht_capab, -#ifdef CONFIG_IWLWIFI_HT_AGG - .ht_tx_agg_start = iwl_mac_ht_tx_agg_start, - .ht_tx_agg_stop = iwl_mac_ht_tx_agg_stop, - .ht_rx_agg_start = iwl_mac_ht_rx_agg_start, - .ht_rx_agg_stop = iwl_mac_ht_rx_agg_stop, -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ - .hw_scan = iwl_mac_hw_scan +static struct ieee80211_ops iwl4965_hw_ops = { + .tx = iwl4965_mac_tx, + .start = iwl4965_mac_start, + .stop = iwl4965_mac_stop, + .add_interface = iwl4965_mac_add_interface, + .remove_interface = iwl4965_mac_remove_interface, + .config = iwl4965_mac_config, + .config_interface = iwl4965_mac_config_interface, + .configure_filter = iwl4965_configure_filter, + .set_key = iwl4965_mac_set_key, + .get_stats = iwl4965_mac_get_stats, + .get_tx_stats = iwl4965_mac_get_tx_stats, + .conf_tx = iwl4965_mac_conf_tx, + .get_tsf = iwl4965_mac_get_tsf, + .reset_tsf = iwl4965_mac_reset_tsf, + .beacon_update = iwl4965_mac_beacon_update, + .erp_ie_changed = iwl4965_mac_erp_ie_changed, +#ifdef CONFIG_IWL4965_HT + .conf_ht = iwl4965_mac_conf_ht, +#ifdef CONFIG_IWL4965_HT_AGG + .ht_tx_agg_start = iwl4965_mac_ht_tx_agg_start, + .ht_tx_agg_stop = iwl4965_mac_ht_tx_agg_stop, + .ht_rx_agg_start = iwl4965_mac_ht_rx_agg_start, + .ht_rx_agg_stop = iwl4965_mac_ht_rx_agg_stop, +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ + .hw_scan = iwl4965_mac_hw_scan }; -static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; - struct iwl_priv *priv; + struct iwl4965_priv *priv; struct ieee80211_hw *hw; int i; - if (iwl_param_disable_hw_scan) { + /* Disabling hardware scan means that mac80211 will perform scans + * "the hard way", rather than using device's scan. */ + if (iwl4965_param_disable_hw_scan) { IWL_DEBUG_INFO("Disabling hw_scan\n"); - iwl_hw_ops.hw_scan = NULL; + iwl4965_hw_ops.hw_scan = NULL; } - if ((iwl_param_queues_num > IWL_MAX_NUM_QUEUES) || - (iwl_param_queues_num < IWL_MIN_NUM_QUEUES)) { + if ((iwl4965_param_queues_num > IWL_MAX_NUM_QUEUES) || + (iwl4965_param_queues_num < IWL_MIN_NUM_QUEUES)) { IWL_ERROR("invalid queues_num, should be between %d and %d\n", IWL_MIN_NUM_QUEUES, IWL_MAX_NUM_QUEUES); err = -EINVAL; @@ -8956,7 +9085,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* mac80211 allocates memory for this device instance, including * space for this driver's private structure */ - hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwl_hw_ops); + hw = ieee80211_alloc_hw(sizeof(struct iwl4965_priv), &iwl4965_hw_ops); if (hw == NULL) { IWL_ERROR("Can not allocate network device\n"); err = -ENOMEM; @@ -8971,9 +9100,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->hw = hw; priv->pci_dev = pdev; - priv->antenna = (enum iwl_antenna)iwl_param_antenna; -#ifdef CONFIG_IWLWIFI_DEBUG - iwl_debug_level = iwl_param_debug; + priv->antenna = (enum iwl4965_antenna)iwl4965_param_antenna; +#ifdef CONFIG_IWL4965_DEBUG + iwl4965_debug_level = iwl4965_param_debug; atomic_set(&priv->restrict_refcnt, 0); #endif priv->retry_rate = 1; @@ -8992,12 +9121,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Tell mac80211 our Tx characteristics */ hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; + /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG +#ifdef CONFIG_IWL4965_HT +#ifdef CONFIG_IWL4965_HT_AGG + /* Enhanced value; more queues, to support 11n aggregation */ hw->queues = 16; -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ +#endif /* CONFIG_IWL4965_HT_AGG */ +#endif /* CONFIG_IWL4965_HT */ spin_lock_init(&priv->lock); spin_lock_init(&priv->power_data.lock); @@ -9018,7 +9149,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - iwl_clear_stations_table(priv); + /* Clear the driver's (not device's) station table */ + iwl4965_clear_stations_table(priv); priv->data_retry_limit = -1; priv->ieee_channels = NULL; @@ -9037,9 +9169,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = pci_request_regions(pdev, DRV_NAME); if (err) goto out_pci_disable_device; + /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, 0x41, 0x00); + priv->hw_base = pci_iomap(pdev, 0, 0); if (!priv->hw_base) { err = -ENODEV; @@ -9052,7 +9186,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Initialize module parameter values here */ - if (iwl_param_disable) { + /* Disable radio (SW RF KILL) via parameter when loading driver */ + if (iwl4965_param_disable) { set_bit(STATUS_RF_KILL_SW, &priv->status); IWL_DEBUG_INFO("Radio disabled.\n"); } @@ -9061,47 +9196,46 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->ps_mode = 0; priv->use_ant_b_for_management_frame = 1; /* start with ant B */ - priv->is_ht_enabled = 1; - priv->channel_width = IWL_CHANNEL_WIDTH_40MHZ; priv->valid_antenna = 0x7; /* assume all 3 connected */ priv->ps_mode = IWL_MIMO_PS_NONE; - priv->cck_power_index_compensation = iwl_read32( - priv, CSR_HW_REV_WA_REG); + /* Choose which receivers/antennas to use */ iwl4965_set_rxon_chain(priv); printk(KERN_INFO DRV_NAME ": Detected Intel Wireless WiFi Link 4965AGN\n"); /* Device-specific setup */ - if (iwl_hw_set_hw_setting(priv)) { + if (iwl4965_hw_set_hw_setting(priv)) { IWL_ERROR("failed to set hw settings\n"); mutex_unlock(&priv->mutex); goto out_iounmap; } -#ifdef CONFIG_IWLWIFI_QOS - if (iwl_param_qos_enable) +#ifdef CONFIG_IWL4965_QOS + if (iwl4965_param_qos_enable) priv->qos_data.qos_enable = 1; - iwl_reset_qos(priv); + iwl4965_reset_qos(priv); priv->qos_data.qos_active = 0; priv->qos_data.qos_cap.val = 0; -#endif /* CONFIG_IWLWIFI_QOS */ +#endif /* CONFIG_IWL4965_QOS */ - iwl_set_rxon_channel(priv, MODE_IEEE80211G, 6); - iwl_setup_deferred_work(priv); - iwl_setup_rx_handlers(priv); + iwl4965_set_rxon_channel(priv, MODE_IEEE80211G, 6); + iwl4965_setup_deferred_work(priv); + iwl4965_setup_rx_handlers(priv); priv->rates_mask = IWL_RATES_MASK; /* If power management is turned on, default to AC mode */ priv->power_mode = IWL_POWER_AC; priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; + iwl4965_disable_interrupts(priv); + pci_enable_msi(pdev); - err = request_irq(pdev->irq, iwl_isr, IRQF_SHARED, DRV_NAME, priv); + err = request_irq(pdev->irq, iwl4965_isr, IRQF_SHARED, DRV_NAME, priv); if (err) { IWL_ERROR("Error allocating IRQ %d\n", pdev->irq); goto out_disable_msi; @@ -9109,7 +9243,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mutex_lock(&priv->mutex); - err = sysfs_create_group(&pdev->dev.kobj, &iwl_attribute_group); + err = sysfs_create_group(&pdev->dev.kobj, &iwl4965_attribute_group); if (err) { IWL_ERROR("failed to create sysfs device attributes\n"); mutex_unlock(&priv->mutex); @@ -9118,7 +9252,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* fetch ucode file from disk, alloc and copy to bus-master buffers ... * ucode filename and max sizes are card-specific. */ - err = iwl_read_ucode(priv); + err = iwl4965_read_ucode(priv); if (err) { IWL_ERROR("Could not read microcode: %d\n", err); mutex_unlock(&priv->mutex); @@ -9127,16 +9261,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mutex_unlock(&priv->mutex); - IWL_DEBUG_INFO("Queing UP work.\n"); + IWL_DEBUG_INFO("Queueing UP work.\n"); queue_work(priv->workqueue, &priv->up); return 0; out_pci_alloc: - iwl_dealloc_ucode_pci(priv); + iwl4965_dealloc_ucode_pci(priv); - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); out_release_irq: free_irq(pdev->irq, priv); @@ -9145,7 +9279,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_disable_msi(pdev); destroy_workqueue(priv->workqueue); priv->workqueue = NULL; - iwl_unset_hw_setting(priv); + iwl4965_unset_hw_setting(priv); out_iounmap: pci_iounmap(pdev, priv->hw_base); @@ -9160,9 +9294,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return err; } -static void iwl_pci_remove(struct pci_dev *pdev) +static void iwl4965_pci_remove(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl4965_priv *priv = pci_get_drvdata(pdev); struct list_head *p, *q; int i; @@ -9173,37 +9307,37 @@ static void iwl_pci_remove(struct pci_dev *pdev) mutex_lock(&priv->mutex); set_bit(STATUS_EXIT_PENDING, &priv->status); - __iwl_down(priv); + __iwl4965_down(priv); mutex_unlock(&priv->mutex); /* Free MAC hash list for ADHOC */ for (i = 0; i < IWL_IBSS_MAC_HASH_SIZE; i++) { list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) { list_del(p); - kfree(list_entry(p, struct iwl_ibss_seq, list)); + kfree(list_entry(p, struct iwl4965_ibss_seq, list)); } } - sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group); + sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); - iwl_dealloc_ucode_pci(priv); + iwl4965_dealloc_ucode_pci(priv); if (priv->rxq.bd) - iwl_rx_queue_free(priv, &priv->rxq); - iwl_hw_txq_ctx_free(priv); + iwl4965_rx_queue_free(priv, &priv->rxq); + iwl4965_hw_txq_ctx_free(priv); - iwl_unset_hw_setting(priv); - iwl_clear_stations_table(priv); + iwl4965_unset_hw_setting(priv); + iwl4965_clear_stations_table(priv); if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); - iwl_rate_control_unregister(priv->hw); + iwl4965_rate_control_unregister(priv->hw); } /*netif_stop_queue(dev); */ flush_workqueue(priv->workqueue); - /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes + /* ieee80211_unregister_hw calls iwl4965_mac_stop, which flushes * priv->workqueue... so we can't take down the workqueue * until now... */ destroy_workqueue(priv->workqueue); @@ -9229,16 +9363,16 @@ static void iwl_pci_remove(struct pci_dev *pdev) #ifdef CONFIG_PM -static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int iwl4965_pci_suspend(struct pci_dev *pdev, pm_message_t state) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl4965_priv *priv = pci_get_drvdata(pdev); mutex_lock(&priv->mutex); set_bit(STATUS_IN_SUSPEND, &priv->status); /* Take down the device; powers it off, etc. */ - __iwl_down(priv); + __iwl4965_down(priv); if (priv->mac80211_registered) ieee80211_stop_queues(priv->hw); @@ -9252,7 +9386,7 @@ static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) return 0; } -static void iwl_resume(struct iwl_priv *priv) +static void iwl4965_resume(struct iwl4965_priv *priv) { unsigned long flags; @@ -9261,47 +9395,47 @@ static void iwl_resume(struct iwl_priv *priv) * Without all of the following, resume will not attempt to take * down the NIC (it shouldn't really need to) and will just try * and bring the NIC back up. However that fails during the - * ucode verification process. This then causes iwl_down to be - * called *after* iwl_hw_nic_init() has succeeded -- which + * ucode verification process. This then causes iwl4965_down to be + * called *after* iwl4965_hw_nic_init() has succeeded -- which * then lets the next init sequence succeed. So, we've * replicated all of that NIC init code here... */ - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_hw_nic_init(priv); + iwl4965_hw_nic_init(priv); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write32(priv, CSR_INT, 0xFFFFFFFF); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_INT, 0xFFFFFFFF); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl4965_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* tell the device to stop sending interrupts */ - iwl_disable_interrupts(priv); + iwl4965_disable_interrupts(priv); spin_lock_irqsave(&priv->lock, flags); - iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + iwl4965_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); - if (!iwl_grab_restricted_access(priv)) { - iwl_write_restricted_reg(priv, APMG_CLK_DIS_REG, - APMG_CLK_VAL_DMA_CLK_RQT); - iwl_release_restricted_access(priv); + if (!iwl4965_grab_nic_access(priv)) { + iwl4965_write_prph(priv, APMG_CLK_DIS_REG, + APMG_CLK_VAL_DMA_CLK_RQT); + iwl4965_release_nic_access(priv); } spin_unlock_irqrestore(&priv->lock, flags); udelay(5); - iwl_hw_nic_reset(priv); + iwl4965_hw_nic_reset(priv); /* Bring the device back up */ clear_bit(STATUS_IN_SUSPEND, &priv->status); queue_work(priv->workqueue, &priv->up); } -static int iwl_pci_resume(struct pci_dev *pdev) +static int iwl4965_pci_resume(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl4965_priv *priv = pci_get_drvdata(pdev); int err; printk(KERN_INFO "Coming out of suspend...\n"); @@ -9320,7 +9454,7 @@ static int iwl_pci_resume(struct pci_dev *pdev) */ pci_write_config_byte(pdev, 0x41, 0x00); - iwl_resume(priv); + iwl4965_resume(priv); mutex_unlock(&priv->mutex); return 0; @@ -9334,33 +9468,33 @@ static int iwl_pci_resume(struct pci_dev *pdev) * *****************************************************************************/ -static struct pci_driver iwl_driver = { +static struct pci_driver iwl4965_driver = { .name = DRV_NAME, - .id_table = iwl_hw_card_ids, - .probe = iwl_pci_probe, - .remove = __devexit_p(iwl_pci_remove), + .id_table = iwl4965_hw_card_ids, + .probe = iwl4965_pci_probe, + .remove = __devexit_p(iwl4965_pci_remove), #ifdef CONFIG_PM - .suspend = iwl_pci_suspend, - .resume = iwl_pci_resume, + .suspend = iwl4965_pci_suspend, + .resume = iwl4965_pci_resume, #endif }; -static int __init iwl_init(void) +static int __init iwl4965_init(void) { int ret; printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n"); printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); - ret = pci_register_driver(&iwl_driver); + ret = pci_register_driver(&iwl4965_driver); if (ret) { IWL_ERROR("Unable to initialize PCI module\n"); return ret; } -#ifdef CONFIG_IWLWIFI_DEBUG - ret = driver_create_file(&iwl_driver.driver, &driver_attr_debug_level); +#ifdef CONFIG_IWL4965_DEBUG + ret = driver_create_file(&iwl4965_driver.driver, &driver_attr_debug_level); if (ret) { IWL_ERROR("Unable to create driver sysfs file\n"); - pci_unregister_driver(&iwl_driver); + pci_unregister_driver(&iwl4965_driver); return ret; } #endif @@ -9368,32 +9502,34 @@ static int __init iwl_init(void) return ret; } -static void __exit iwl_exit(void) +static void __exit iwl4965_exit(void) { -#ifdef CONFIG_IWLWIFI_DEBUG - driver_remove_file(&iwl_driver.driver, &driver_attr_debug_level); +#ifdef CONFIG_IWL4965_DEBUG + driver_remove_file(&iwl4965_driver.driver, &driver_attr_debug_level); #endif - pci_unregister_driver(&iwl_driver); + pci_unregister_driver(&iwl4965_driver); } -module_param_named(antenna, iwl_param_antenna, int, 0444); +module_param_named(antenna, iwl4965_param_antenna, int, 0444); MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); -module_param_named(disable, iwl_param_disable, int, 0444); +module_param_named(disable, iwl4965_param_disable, int, 0444); MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])"); -module_param_named(hwcrypto, iwl_param_hwcrypto, int, 0444); +module_param_named(hwcrypto, iwl4965_param_hwcrypto, int, 0444); MODULE_PARM_DESC(hwcrypto, "using hardware crypto engine (default 0 [software])\n"); -module_param_named(debug, iwl_param_debug, int, 0444); +module_param_named(debug, iwl4965_param_debug, int, 0444); MODULE_PARM_DESC(debug, "debug output mask"); -module_param_named(disable_hw_scan, iwl_param_disable_hw_scan, int, 0444); +module_param_named(disable_hw_scan, iwl4965_param_disable_hw_scan, int, 0444); MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); -module_param_named(queues_num, iwl_param_queues_num, int, 0444); +module_param_named(queues_num, iwl4965_param_queues_num, int, 0444); MODULE_PARM_DESC(queues_num, "number of hw queues."); /* QoS */ -module_param_named(qos_enable, iwl_param_qos_enable, int, 0444); +module_param_named(qos_enable, iwl4965_param_qos_enable, int, 0444); MODULE_PARM_DESC(qos_enable, "enable all QoS functionality"); +module_param_named(amsdu_size_8K, iwl4965_param_amsdu_size_8K, int, 0444); +MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size"); -module_exit(iwl_exit); -module_init(iwl_init); +module_exit(iwl4965_exit); +module_init(iwl4965_init); diff --git a/drivers/net/wireless/iwlwifi/iwlwifi.h b/drivers/net/wireless/iwlwifi/iwlwifi.h deleted file mode 100644 index 432ce88..0000000 --- a/drivers/net/wireless/iwlwifi/iwlwifi.h +++ /dev/null @@ -1,708 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2003 - 2007 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: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - *****************************************************************************/ - -#ifndef __iwlwifi_h__ -#define __iwlwifi_h__ - -#include /* for struct pci_device_id */ -#include -#include - -struct iwl_priv; - -/* Hardware specific file defines the PCI IDs table for that hardware module */ -extern struct pci_device_id iwl_hw_card_ids[]; - -#include "iwl-hw.h" -#if IWL == 3945 -#define DRV_NAME "iwl3945" -#include "iwl-3945-hw.h" -#elif IWL == 4965 -#define DRV_NAME "iwl4965" -#include "iwl-4965-hw.h" -#endif - -#include "iwl-prph.h" - -/* - * Driver implementation data structures, constants, inline - * functions - * - * NOTE: DO NOT PUT HARDWARE/UCODE SPECIFIC DECLRATIONS HERE - * - * Hardware specific declrations go into iwl-*hw.h - * - */ - -#include "iwl-debug.h" - -/* Default noise level to report when noise measurement is not available. - * This may be because we're: - * 1) Not associated (4965, no beacon statistics being sent to driver) - * 2) Scanning (noise measurement does not apply to associated channel) - * 3) Receiving CCK (3945 delivers noise info only for OFDM frames) - * Use default noise value of -127 ... this is below the range of measurable - * Rx dBm for either 3945 or 4965, so it can indicate "unmeasurable" to user. - * Also, -127 works better than 0 when averaging frames with/without - * noise info (e.g. averaging might be done in app); measured dBm values are - * always negative ... using a negative value as the default keeps all - * averages within an s8's (used in some apps) range of negative values. */ -#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) - -/* Module parameters accessible from iwl-*.c */ -extern int iwl_param_disable_hw_scan; -extern int iwl_param_debug; -extern int iwl_param_mode; -extern int iwl_param_disable; -extern int iwl_param_antenna; -extern int iwl_param_hwcrypto; -extern int iwl_param_qos_enable; -extern int iwl_param_queues_num; - -enum iwl_antenna { - IWL_ANTENNA_DIVERSITY, - IWL_ANTENNA_MAIN, - IWL_ANTENNA_AUX -}; - -/* - * RTS threshold here is total size [2347] minus 4 FCS bytes - * Per spec: - * a value of 0 means RTS on all data/management packets - * a value > max MSDU size means no RTS - * else RTS for data/management frames where MPDU is larger - * than RTS value. - */ -#define DEFAULT_RTS_THRESHOLD 2347U -#define MIN_RTS_THRESHOLD 0U -#define MAX_RTS_THRESHOLD 2347U -#define MAX_MSDU_SIZE 2304U -#define MAX_MPDU_SIZE 2346U -#define DEFAULT_BEACON_INTERVAL 100U -#define DEFAULT_SHORT_RETRY_LIMIT 7U -#define DEFAULT_LONG_RETRY_LIMIT 4U - -struct iwl_rx_mem_buffer { - dma_addr_t dma_addr; - struct sk_buff *skb; - struct list_head list; -}; - -struct iwl_rt_rx_hdr { - struct ieee80211_radiotap_header rt_hdr; - __le64 rt_tsf; /* TSF */ - u8 rt_flags; /* radiotap packet flags */ - u8 rt_rate; /* rate in 500kb/s */ - __le16 rt_channelMHz; /* channel in MHz */ - __le16 rt_chbitmask; /* channel bitfield */ - s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ - s8 rt_dbmnoise; - u8 rt_antenna; /* antenna number */ - u8 payload[0]; /* payload... */ -} __attribute__ ((packed)); - -struct iwl_rt_tx_hdr { - struct ieee80211_radiotap_header rt_hdr; - u8 rt_rate; /* rate in 500kb/s */ - __le16 rt_channel; /* channel in mHz */ - __le16 rt_chbitmask; /* channel bitfield */ - s8 rt_dbmsignal; /* signal in dBm, kluged to signed */ - u8 rt_antenna; /* antenna number */ - u8 payload[0]; /* payload... */ -} __attribute__ ((packed)); - -/* - * Generic queue structure - * - * Contains common data for Rx and Tx queues - */ -struct iwl_queue { - int n_bd; /* number of BDs in this queue */ - int first_empty; /* 1-st empty entry (index) host_w*/ - int last_used; /* last used entry (index) host_r*/ - dma_addr_t dma_addr; /* physical addr for BD's */ - int n_window; /* safe queue window */ - u32 id; - int low_mark; /* low watermark, resume queue if free - * space more than this */ - int high_mark; /* high watermark, stop queue if free - * space less than this */ -} __attribute__ ((packed)); - -#define MAX_NUM_OF_TBS (20) - -struct iwl_tx_info { - struct ieee80211_tx_status status; - struct sk_buff *skb[MAX_NUM_OF_TBS]; -}; - -/** - * struct iwl_tx_queue - Tx Queue for DMA - * @need_update: need to update read/write index - * @shed_retry: queue is HT AGG enabled - * - * Queue consists of circular buffer of BD's and required locking structures. - */ -struct iwl_tx_queue { - struct iwl_queue q; - struct iwl_tfd_frame *bd; - struct iwl_cmd *cmd; - dma_addr_t dma_addr_cmd; - struct iwl_tx_info *txb; - int need_update; - int sched_retry; - int active; -}; - -#include "iwl-channel.h" - -#if IWL == 3945 -#include "iwl-3945-rs.h" -#else -#include "iwl-4965-rs.h" -#endif - -#define IWL_TX_FIFO_AC0 0 -#define IWL_TX_FIFO_AC1 1 -#define IWL_TX_FIFO_AC2 2 -#define IWL_TX_FIFO_AC3 3 -#define IWL_TX_FIFO_HCCA_1 5 -#define IWL_TX_FIFO_HCCA_2 6 -#define IWL_TX_FIFO_NONE 7 - -/* Minimum number of queues. MAX_NUM is defined in hw specific files */ -#define IWL_MIN_NUM_QUEUES 4 - -/* Power management (not Tx power) structures */ - -struct iwl_power_vec_entry { - struct iwl_powertable_cmd cmd; - u8 no_dtim; -}; -#define IWL_POWER_RANGE_0 (0) -#define IWL_POWER_RANGE_1 (1) - -#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */ -#define IWL_POWER_INDEX_3 0x03 -#define IWL_POWER_INDEX_5 0x05 -#define IWL_POWER_AC 0x06 -#define IWL_POWER_BATTERY 0x07 -#define IWL_POWER_LIMIT 0x07 -#define IWL_POWER_MASK 0x0F -#define IWL_POWER_ENABLED 0x10 -#define IWL_POWER_LEVEL(x) ((x) & IWL_POWER_MASK) - -struct iwl_power_mgr { - spinlock_t lock; - struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC]; - struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC]; - u8 active_index; - u32 dtim_val; -}; - -#define IEEE80211_DATA_LEN 2304 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) - -struct iwl_frame { - union { - struct ieee80211_hdr frame; - struct iwl_tx_beacon_cmd beacon; - u8 raw[IEEE80211_FRAME_LEN]; - u8 cmd[360]; - } u; - struct list_head list; -}; - -#define SEQ_TO_QUEUE(x) ((x >> 8) & 0xbf) -#define QUEUE_TO_SEQ(x) ((x & 0xbf) << 8) -#define SEQ_TO_INDEX(x) (x & 0xff) -#define INDEX_TO_SEQ(x) (x & 0xff) -#define SEQ_HUGE_FRAME (0x4000) -#define SEQ_RX_FRAME __constant_cpu_to_le16(0x8000) -#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) -#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) -#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) - -enum { - /* CMD_SIZE_NORMAL = 0, */ - CMD_SIZE_HUGE = (1 << 0), - /* CMD_SYNC = 0, */ - CMD_ASYNC = (1 << 1), - /* CMD_NO_SKB = 0, */ - CMD_WANT_SKB = (1 << 2), -}; - -struct iwl_cmd; -struct iwl_priv; - -struct iwl_cmd_meta { - struct iwl_cmd_meta *source; - union { - struct sk_buff *skb; - int (*callback)(struct iwl_priv *priv, - struct iwl_cmd *cmd, struct sk_buff *skb); - } __attribute__ ((packed)) u; - - /* The CMD_SIZE_HUGE flag bit indicates that the command - * structure is stored at the end of the shared queue memory. */ - u32 flags; - -} __attribute__ ((packed)); - -struct iwl_cmd { - struct iwl_cmd_meta meta; - struct iwl_cmd_header hdr; - union { - struct iwl_addsta_cmd addsta; - struct iwl_led_cmd led; - u32 flags; - u8 val8; - u16 val16; - u32 val32; - struct iwl_bt_cmd bt; - struct iwl_rxon_time_cmd rxon_time; - struct iwl_powertable_cmd powertable; - struct iwl_qosparam_cmd qosparam; - struct iwl_tx_cmd tx; - struct iwl_tx_beacon_cmd tx_beacon; - struct iwl_rxon_assoc_cmd rxon_assoc; - u8 *indirect; - u8 payload[360]; - } __attribute__ ((packed)) cmd; -} __attribute__ ((packed)); - -struct iwl_host_cmd { - u8 id; - u16 len; - struct iwl_cmd_meta meta; - const void *data; -}; - -#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \ - sizeof(struct iwl_cmd_meta)) - -/* - * RX related structures and functions - */ -#define RX_FREE_BUFFERS 64 -#define RX_LOW_WATERMARK 8 - -#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 -#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 -#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 - -/** - * struct iwl_rx_queue - Rx queue - * @processed: Internal index to last handled Rx packet - * @read: Shared index to newest available Rx buffer - * @write: Shared index to oldest written Rx packet - * @free_count: Number of pre-allocated buffers in rx_free - * @rx_free: list of free SKBs for use - * @rx_used: List of Rx buffers with no SKB - * @need_update: flag to indicate we need to update read/write index - * - * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers - */ -struct iwl_rx_queue { - __le32 *bd; - dma_addr_t dma_addr; - struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; - struct iwl_rx_mem_buffer *queue[RX_QUEUE_SIZE]; - u32 processed; - u32 read; - u32 write; - u32 free_count; - struct list_head rx_free; - struct list_head rx_used; - int need_update; - spinlock_t lock; -}; - -#define IWL_SUPPORTED_RATES_IE_LEN 8 - -#define SCAN_INTERVAL 100 - -#define MAX_A_CHANNELS 252 -#define MIN_A_CHANNELS 7 - -#define MAX_B_CHANNELS 14 -#define MIN_B_CHANNELS 1 - -#define STATUS_HCMD_ACTIVE 0 /* host command in progress */ -#define STATUS_INT_ENABLED 1 -#define STATUS_RF_KILL_HW 2 -#define STATUS_RF_KILL_SW 3 -#define STATUS_INIT 4 -#define STATUS_ALIVE 5 -#define STATUS_READY 6 -#define STATUS_TEMPERATURE 7 -#define STATUS_GEO_CONFIGURED 8 -#define STATUS_EXIT_PENDING 9 -#define STATUS_IN_SUSPEND 10 -#define STATUS_STATISTICS 11 -#define STATUS_SCANNING 12 -#define STATUS_SCAN_ABORTING 13 -#define STATUS_SCAN_HW 14 -#define STATUS_POWER_PMI 15 -#define STATUS_FW_ERROR 16 - -#define MAX_TID_COUNT 9 - -#define IWL_INVALID_RATE 0xFF -#define IWL_INVALID_VALUE -1 - -#if IWL == 4965 -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG -struct iwl_ht_agg { - u16 txq_id; - u16 frame_count; - u16 wait_for_ba; - u16 start_idx; - u32 bitmap0; - u32 bitmap1; - u32 rate_n_flags; -}; -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ -#endif - -struct iwl_tid_data { - u16 seq_number; -#if IWL == 4965 -#ifdef CONFIG_IWLWIFI_HT -#ifdef CONFIG_IWLWIFI_HT_AGG - struct iwl_ht_agg agg; -#endif /* CONFIG_IWLWIFI_HT_AGG */ -#endif /* CONFIG_IWLWIFI_HT */ -#endif -}; - -struct iwl_hw_key { - enum ieee80211_key_alg alg; - int keylen; - u8 key[32]; -}; - -union iwl_ht_rate_supp { - u16 rates; - struct { - u8 siso_rate; - u8 mimo_rate; - }; -}; - -#ifdef CONFIG_IWLWIFI_HT -#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) -#define HT_IE_MAX_AMSDU_SIZE_4K (0) -#define CFG_HT_MPDU_DENSITY_2USEC (0x5) -#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC - -struct sta_ht_info { - u8 is_ht; - u16 rx_mimo_ps_mode; - u16 tx_mimo_ps_mode; - u16 control_channel; - u8 max_amsdu_size; - u8 ampdu_factor; - u8 mpdu_density; - u8 operating_mode; - u8 supported_chan_width; - u8 extension_chan_offset; - u8 is_green_field; - u8 sgf; - u8 supp_rates[16]; - u8 tx_chan_width; - u8 chan_width_cap; -}; -#endif /*CONFIG_IWLWIFI_HT */ - -#ifdef CONFIG_IWLWIFI_QOS - -union iwl_qos_capabity { - struct { - u8 edca_count:4; /* bit 0-3 */ - u8 q_ack:1; /* bit 4 */ - u8 queue_request:1; /* bit 5 */ - u8 txop_request:1; /* bit 6 */ - u8 reserved:1; /* bit 7 */ - } q_AP; - struct { - u8 acvo_APSD:1; /* bit 0 */ - u8 acvi_APSD:1; /* bit 1 */ - u8 ac_bk_APSD:1; /* bit 2 */ - u8 ac_be_APSD:1; /* bit 3 */ - u8 q_ack:1; /* bit 4 */ - u8 max_len:2; /* bit 5-6 */ - u8 more_data_ack:1; /* bit 7 */ - } q_STA; - u8 val; -}; - -/* QoS sturctures */ -struct iwl_qos_info { - int qos_enable; - int qos_active; - union iwl_qos_capabity qos_cap; - struct iwl_qosparam_cmd def_qos_parm; -}; -#endif /*CONFIG_IWLWIFI_QOS */ - -#define STA_PS_STATUS_WAKE 0 -#define STA_PS_STATUS_SLEEP 1 - -struct iwl_station_entry { - struct iwl_addsta_cmd sta; - struct iwl_tid_data tid[MAX_TID_COUNT]; -#if IWL == 3945 - union { - struct { - u8 rate; - u8 flags; - } s; - u16 rate_n_flags; - } current_rate; -#endif - u8 used; - u8 ps_status; - struct iwl_hw_key keyinfo; -}; - -/* one for each uCode image (inst/data, boot/init/runtime) */ -struct fw_image_desc { - void *v_addr; /* access by driver */ - dma_addr_t p_addr; /* access by card's busmaster DMA */ - u32 len; /* bytes */ -}; - -/* uCode file layout */ -struct iwl_ucode { - __le32 ver; /* major/minor/subminor */ - __le32 inst_size; /* bytes of runtime instructions */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of initialization instructions */ - __le32 init_data_size; /* bytes of initialization data */ - __le32 boot_size; /* bytes of bootstrap instructions */ - u8 data[0]; /* data in same order as "size" elements */ -}; - -#define IWL_IBSS_MAC_HASH_SIZE 32 - -struct iwl_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num; - u16 frag_num; - unsigned long packet_time; - struct list_head list; -}; - -struct iwl_driver_hw_info { - u16 max_txq_num; - u16 ac_queue_count; - u32 rx_buffer_size; - u16 tx_cmd_len; - u16 max_rxq_size; - u16 max_rxq_log; - u32 cck_flag; - u8 max_stations; - u8 bcast_sta_id; - void *shared_virt; - dma_addr_t shared_phys; -}; - - -#define STA_FLG_RTS_MIMO_PROT_MSK __constant_cpu_to_le32(1 << 17) -#define STA_FLG_AGG_MPDU_8US_MSK __constant_cpu_to_le32(1 << 18) -#define STA_FLG_MAX_AGG_SIZE_POS (19) -#define STA_FLG_MAX_AGG_SIZE_MSK __constant_cpu_to_le32(3 << 19) -#define STA_FLG_FAT_EN_MSK __constant_cpu_to_le32(1 << 21) -#define STA_FLG_MIMO_DIS_MSK __constant_cpu_to_le32(1 << 22) -#define STA_FLG_AGG_MPDU_DENSITY_POS (23) -#define STA_FLG_AGG_MPDU_DENSITY_MSK __constant_cpu_to_le32(7 << 23) -#define HT_SHORT_GI_20MHZ_ONLY (1 << 0) -#define HT_SHORT_GI_40MHZ_ONLY (1 << 1) - - -#include "iwl-priv.h" - -/* Requires full declaration of iwl_priv before including */ -#include "iwl-io.h" - -#define IWL_RX_HDR(x) ((struct iwl_rx_frame_hdr *)(\ - x->u.rx_frame.stats.payload + \ - x->u.rx_frame.stats.phy_count)) -#define IWL_RX_END(x) ((struct iwl_rx_frame_end *)(\ - IWL_RX_HDR(x)->payload + \ - le16_to_cpu(IWL_RX_HDR(x)->len))) -#define IWL_RX_STATS(x) (&x->u.rx_frame.stats) -#define IWL_RX_DATA(x) (IWL_RX_HDR(x)->payload) - - -/****************************************************************************** - * - * Functions implemented in iwl-base.c which are forward declared here - * for use by iwl-*.c - * - *****************************************************************************/ -struct iwl_addsta_cmd; -extern int iwl_send_add_station(struct iwl_priv *priv, - struct iwl_addsta_cmd *sta, u8 flags); -extern const char *iwl_get_tx_fail_reason(u32 status); -extern u8 iwl_add_station(struct iwl_priv *priv, const u8 *bssid, - int is_ap, u8 flags); -extern int iwl_is_network_packet(struct iwl_priv *priv, - struct ieee80211_hdr *header); -extern int iwl_power_init_handle(struct iwl_priv *priv); -extern int iwl_eeprom_init(struct iwl_priv *priv); -#ifdef CONFIG_IWLWIFI_DEBUG -extern void iwl_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - struct ieee80211_hdr *header, int group100); -#else -static inline void iwl_report_frame(struct iwl_priv *priv, - struct iwl_rx_packet *pkt, - struct ieee80211_hdr *header, - int group100) {} -#endif -extern int iwl_tx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern void iwl_handle_data_packet_monitor(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb, - void *data, short len, - struct ieee80211_rx_status *stats, - u16 phy_flags); -extern int is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr - *header); -extern void iwl_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq); -extern int iwl_rx_queue_alloc(struct iwl_priv *priv); -extern void iwl_rx_queue_reset(struct iwl_priv *priv, - struct iwl_rx_queue *rxq); -extern int iwl_calc_db_from_ratio(int sig_ratio); -extern int iwl_calc_sig_qual(int rssi_dbm, int noise_dbm); -extern int iwl_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq, int count, u32 id); -extern int iwl_rx_queue_restock(struct iwl_priv *priv); -extern void iwl_rx_replenish(void *data); -extern void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq); -extern int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, - const void *data); -extern int __must_check iwl_send_cmd_async(struct iwl_priv *priv, - struct iwl_host_cmd *cmd); -extern int __must_check iwl_send_cmd_sync(struct iwl_priv *priv, - struct iwl_host_cmd *cmd); -extern int __must_check iwl_send_cmd(struct iwl_priv *priv, - struct iwl_host_cmd *cmd); -extern unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - const u8 *dest, int left); -extern int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, - struct iwl_rx_queue *q); -extern int iwl_send_statistics_request(struct iwl_priv *priv); -extern void iwl_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb, - u32 decrypt_res, - struct ieee80211_rx_status *stats); -extern __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr); - -extern const u8 BROADCAST_ADDR[ETH_ALEN]; - -/* - * Currently used by iwl-3945-rs... look at restructuring so that it doesn't - * call this... todo... fix that. -*/ -extern u8 iwl_sync_station(struct iwl_priv *priv, int sta_id, - u16 tx_rate, u8 flags); - -static inline int iwl_is_associated(struct iwl_priv *priv) -{ - return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; -} - -/****************************************************************************** - * - * Functions implemented in iwl-[34]*.c which are forward declared here - * for use by iwl-base.c - * - * NOTE: The implementation of these functions are hardware specific - * which is why they are in the hardware specific files (vs. iwl-base.c) - * - * Naming convention -- - * iwl_ <-- Its part of iwlwifi (should be changed to iwl_) - * iwl_hw_ <-- Hardware specific (implemented in iwl-XXXX.c by all HW) - * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) - * iwl_bg_ <-- Called from work queue context - * iwl_mac_ <-- mac80211 callback - * - ****************************************************************************/ -extern void iwl_hw_rx_handler_setup(struct iwl_priv *priv); -extern void iwl_hw_setup_deferred_work(struct iwl_priv *priv); -extern void iwl_hw_cancel_deferred_work(struct iwl_priv *priv); -extern int iwl_hw_rxq_stop(struct iwl_priv *priv); -extern int iwl_hw_set_hw_setting(struct iwl_priv *priv); -extern int iwl_hw_nic_init(struct iwl_priv *priv); -extern void iwl_hw_card_show_info(struct iwl_priv *priv); -extern int iwl_hw_nic_stop_master(struct iwl_priv *priv); -extern void iwl_hw_txq_ctx_free(struct iwl_priv *priv); -extern void iwl_hw_txq_ctx_stop(struct iwl_priv *priv); -extern int iwl_hw_nic_reset(struct iwl_priv *priv); -extern int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, - dma_addr_t addr, u16 len); -extern int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); -extern int iwl_hw_get_temperature(struct iwl_priv *priv); -extern int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); -extern unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, - struct iwl_frame *frame, u8 rate); -extern int iwl_hw_get_rx_read(struct iwl_priv *priv); -extern void iwl_hw_build_tx_cmd_rate(struct iwl_priv *priv, - struct iwl_cmd *cmd, - struct ieee80211_tx_control *ctrl, - struct ieee80211_hdr *hdr, - int sta_id, int tx_id); -extern int iwl_hw_reg_send_txpower(struct iwl_priv *priv); -extern int iwl_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); -extern void iwl_hw_rx_statistics(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb); -extern void iwl_disable_events(struct iwl_priv *priv); -extern int iwl4965_get_temperature(const struct iwl_priv *priv); - -/** - * iwl_hw_find_station - Find station id for a given BSSID - * @bssid: MAC address of station ID to find - * - * NOTE: This should not be hardware specific but the code has - * not yet been merged into a single common layer for managing the - * station tables. - */ -extern u8 iwl_hw_find_station(struct iwl_priv *priv, const u8 *bssid); - -extern int iwl_hw_channel_switch(struct iwl_priv *priv, u16 channel); -extern int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index); -#endif diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c index 9cf0211..377dcb5 100644 --- a/drivers/net/wireless/libertas/11d.c +++ b/drivers/net/wireless/libertas/11d.c @@ -43,16 +43,14 @@ static struct chan_freq_power channel_freq_power_UN_BG[] = { {14, 2484, TX_PWR_DEFAULT} }; -static u8 wlan_region_2_code(u8 * region) +static u8 lbs_region_2_code(u8 *region) { u8 i; - u8 size = sizeof(region_code_mapping)/ - sizeof(struct region_code_mapping); for (i = 0; region[i] && i < COUNTRY_CODE_LEN; i++) region[i] = toupper(region[i]); - for (i = 0; i < size; i++) { + for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { if (!memcmp(region, region_code_mapping[i].region, COUNTRY_CODE_LEN)) return (region_code_mapping[i].code); @@ -62,12 +60,11 @@ static u8 wlan_region_2_code(u8 * region) return (region_code_mapping[0].code); } -static u8 *wlan_code_2_region(u8 code) +static u8 *lbs_code_2_region(u8 code) { u8 i; - u8 size = sizeof(region_code_mapping) - / sizeof(struct region_code_mapping); - for (i = 0; i < size; i++) { + + for (i = 0; i < ARRAY_SIZE(region_code_mapping); i++) { if (region_code_mapping[i].code == code) return (region_code_mapping[i].region); } @@ -82,7 +79,7 @@ static u8 *wlan_code_2_region(u8 code) * @param nrchan number of channels * @return the nrchan-th chan number */ -static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan) +static u8 lbs_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 *chan) /*find the nrchan-th chan after the firstchan*/ { u8 i; @@ -90,8 +87,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan) u8 cfp_no; cfp = channel_freq_power_UN_BG; - cfp_no = sizeof(channel_freq_power_UN_BG) / - sizeof(struct chan_freq_power); + cfp_no = ARRAY_SIZE(channel_freq_power_UN_BG); for (i = 0; i < cfp_no; i++) { if ((cfp + i)->channel == firstchan) { @@ -117,7 +113,7 @@ static u8 wlan_get_chan_11d(u8 band, u8 firstchan, u8 nrchan, u8 * chan) * @param parsed_region_chan pointer to parsed_region_chan_11d * @return TRUE; FALSE */ -static u8 wlan_channel_known_11d(u8 chan, +static u8 lbs_channel_known_11d(u8 chan, struct parsed_region_chan_11d * parsed_region_chan) { struct chan_power_11d *chanpwr = parsed_region_chan->chanpwr; @@ -138,19 +134,15 @@ static u8 wlan_channel_known_11d(u8 chan, return 0; } -u32 libertas_chan_2_freq(u8 chan, u8 band) +u32 lbs_chan_2_freq(u8 chan, u8 band) { struct chan_freq_power *cf; - u16 cnt; u16 i; u32 freq = 0; cf = channel_freq_power_UN_BG; - cnt = - sizeof(channel_freq_power_UN_BG) / - sizeof(struct chan_freq_power); - for (i = 0; i < cnt; i++) { + for (i = 0; i < ARRAY_SIZE(channel_freq_power_UN_BG); i++) { if (chan == cf[i].channel) freq = cf[i].freq; } @@ -160,7 +152,7 @@ u32 libertas_chan_2_freq(u8 chan, u8 band) static int generate_domain_info_11d(struct parsed_region_chan_11d *parsed_region_chan, - struct wlan_802_11d_domain_reg * domaininfo) + struct lbs_802_11d_domain_reg *domaininfo) { u8 nr_subband = 0; @@ -225,7 +217,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d * @param *parsed_region_chan pointer to parsed_region_chan_11d * @return N/A */ -static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_chan, +static void lbs_generate_parsed_region_chan_11d(struct region_channel *region_chan, struct parsed_region_chan_11d * parsed_region_chan) { @@ -246,7 +238,7 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_ parsed_region_chan->band = region_chan->band; parsed_region_chan->region = region_chan->region; memcpy(parsed_region_chan->countrycode, - wlan_code_2_region(region_chan->region), COUNTRY_CODE_LEN); + lbs_code_2_region(region_chan->region), COUNTRY_CODE_LEN); lbs_deb_11d("region 0x%x, band %d\n", parsed_region_chan->region, parsed_region_chan->band); @@ -272,7 +264,7 @@ static void wlan_generate_parsed_region_chan_11d(struct region_channel * region_ * @param chan chan * @return TRUE;FALSE */ -static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan) +static u8 lbs_region_chan_supported_11d(u8 region, u8 band, u8 chan) { struct chan_freq_power *cfp; int cfp_no; @@ -281,7 +273,7 @@ static u8 wlan_region_chan_supported_11d(u8 region, u8 band, u8 chan) lbs_deb_enter(LBS_DEB_11D); - cfp = libertas_get_region_cfp_table(region, band, &cfp_no); + cfp = lbs_get_region_cfp_table(region, band, &cfp_no); if (cfp == NULL) return 0; @@ -346,7 +338,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* /*Step1: check region_code */ parsed_region_chan->region = region = - wlan_region_2_code(countryinfo->countrycode); + lbs_region_2_code(countryinfo->countrycode); lbs_deb_11d("regioncode=%x\n", (u8) parsed_region_chan->region); lbs_deb_hex(LBS_DEB_11D, "countrycode", (char *)countryinfo->countrycode, @@ -375,7 +367,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* for (i = 0; idx < MAX_NO_OF_CHAN && i < nrchan; i++) { /*step4: channel is supported? */ - if (!wlan_get_chan_11d(band, firstchan, i, &curchan)) { + if (!lbs_get_chan_11d(band, firstchan, i, &curchan)) { /* Chan is not found in UN table */ lbs_deb_11d("chan is not supported: %d \n", i); break; @@ -383,7 +375,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* lastchan = curchan; - if (wlan_region_chan_supported_11d + if (lbs_region_chan_supported_11d (region, band, curchan)) { /*step5: Check if curchan is supported by mrvl in region */ parsed_region_chan->chanpwr[idx].chan = curchan; @@ -419,14 +411,14 @@ done: * @param parsed_region_chan pointer to parsed_region_chan_11d * @return PASSIVE if chan is unknown; ACTIVE if chan is known */ -u8 libertas_get_scan_type_11d(u8 chan, +u8 lbs_get_scan_type_11d(u8 chan, struct parsed_region_chan_11d * parsed_region_chan) { u8 scan_type = CMD_SCAN_TYPE_PASSIVE; lbs_deb_enter(LBS_DEB_11D); - if (wlan_channel_known_11d(chan, parsed_region_chan)) { + if (lbs_channel_known_11d(chan, parsed_region_chan)) { lbs_deb_11d("found, do active scan\n"); scan_type = CMD_SCAN_TYPE_ACTIVE; } else { @@ -438,7 +430,7 @@ u8 libertas_get_scan_type_11d(u8 chan, } -void libertas_init_11d(wlan_private * priv) +void lbs_init_11d(struct lbs_private *priv) { priv->adapter->enable11d = 0; memset(&(priv->adapter->parsed_region_chan), 0, @@ -448,10 +440,10 @@ void libertas_init_11d(wlan_private * priv) /** * @brief This function sets DOMAIN INFO to FW - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @return 0; -1 */ -static int set_domain_info_11d(wlan_private * priv) +static int set_domain_info_11d(struct lbs_private *priv) { int ret; @@ -460,7 +452,7 @@ static int set_domain_info_11d(wlan_private * priv) return 0; } - ret = libertas_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, + ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); if (ret) @@ -471,13 +463,13 @@ static int set_domain_info_11d(wlan_private * priv) /** * @brief This function setups scan channels - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @param band band * @return 0 */ -int libertas_set_universaltable(wlan_private * priv, u8 band) +int lbs_set_universaltable(struct lbs_private *priv, u8 band) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u16 size = sizeof(struct chan_freq_power); u16 i = 0; @@ -500,20 +492,20 @@ int libertas_set_universaltable(wlan_private * priv, u8 band) /** * @brief This function implements command CMD_802_11D_DOMAIN_INFO - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @param cmd pointer to cmd buffer * @param cmdno cmd ID * @param cmdOption cmd action * @return 0 */ -int libertas_cmd_802_11d_domain_info(wlan_private * priv, +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmdno, u16 cmdoption) { struct cmd_ds_802_11d_domain_info *pdomaininfo = &cmd->params.domaininfo; struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u8 nr_subband = adapter->domainreg.nr_subband; lbs_deb_enter(LBS_DEB_11D); @@ -560,11 +552,11 @@ done: /** * @brief This function parses countryinfo from AP and download country info to FW - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @param resp pointer to command response buffer * @return 0; -1 */ -int libertas_ret_802_11d_domain_info(wlan_private * priv, +int lbs_ret_802_11d_domain_info(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; @@ -606,14 +598,14 @@ int libertas_ret_802_11d_domain_info(wlan_private * priv, /** * @brief This function parses countryinfo from AP and download country info to FW - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @return 0; -1 */ -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, +int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv, struct bss_descriptor * bss) { int ret; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_11D); if (priv->adapter->enable11d) { @@ -628,7 +620,7 @@ int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, } memset(&adapter->domainreg, 0, - sizeof(struct wlan_802_11d_domain_reg)); + sizeof(struct lbs_802_11d_domain_reg)); generate_domain_info_11d(&adapter->parsed_region_chan, &adapter->domainreg); @@ -648,13 +640,13 @@ done: /** * @brief This function generates 11D info from user specified regioncode and download to FW - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @return 0; -1 */ -int libertas_create_dnld_countryinfo_11d(wlan_private * priv) +int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv) { int ret; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct region_channel *region_chan; u8 j; @@ -664,8 +656,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) if (priv->adapter->enable11d) { /* update parsed_region_chan_11; dnld domaininf to FW */ - for (j = 0; j < sizeof(adapter->region_channel) / - sizeof(adapter->region_channel[0]); j++) { + for (j = 0; j < ARRAY_SIZE(adapter->region_channel); j++) { region_chan = &adapter->region_channel[j]; lbs_deb_11d("%d region_chan->band %d\n", j, @@ -679,8 +670,7 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) break; } - if (j >= sizeof(adapter->region_channel) / - sizeof(adapter->region_channel[0])) { + if (j >= ARRAY_SIZE(adapter->region_channel)) { lbs_deb_11d("region_chan not found, band %d\n", adapter->curbssparams.band); ret = -1; @@ -689,12 +679,12 @@ int libertas_create_dnld_countryinfo_11d(wlan_private * priv) memset(&adapter->parsed_region_chan, 0, sizeof(struct parsed_region_chan_11d)); - wlan_generate_parsed_region_chan_11d(region_chan, + lbs_generate_parsed_region_chan_11d(region_chan, &adapter-> parsed_region_chan); memset(&adapter->domainreg, 0, - sizeof(struct wlan_802_11d_domain_reg)); + sizeof(struct lbs_802_11d_domain_reg)); generate_domain_info_11d(&adapter->parsed_region_chan, &adapter->domainreg); diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h index 3a6d1f8..811eea2 100644 --- a/drivers/net/wireless/libertas/11d.h +++ b/drivers/net/wireless/libertas/11d.h @@ -2,8 +2,8 @@ * This header file contains data structures and * function declarations of 802.11d */ -#ifndef _WLAN_11D_ -#define _WLAN_11D_ +#ifndef _LBS_11D_ +#define _LBS_11D_ #include "types.h" #include "defs.h" @@ -52,7 +52,7 @@ struct cmd_ds_802_11d_domain_info { } __attribute__ ((packed)); /** domain regulatory information */ -struct wlan_802_11d_domain_reg { +struct lbs_802_11d_domain_reg { /** country Code*/ u8 countrycode[COUNTRY_CODE_LEN]; /** No. of subband*/ @@ -78,26 +78,28 @@ struct region_code_mapping { u8 code; }; -u8 libertas_get_scan_type_11d(u8 chan, +struct lbs_private; + +u8 lbs_get_scan_type_11d(u8 chan, struct parsed_region_chan_11d *parsed_region_chan); -u32 libertas_chan_2_freq(u8 chan, u8 band); +u32 lbs_chan_2_freq(u8 chan, u8 band); -void libertas_init_11d(wlan_private * priv); +void lbs_init_11d(struct lbs_private *priv); -int libertas_set_universaltable(wlan_private * priv, u8 band); +int lbs_set_universaltable(struct lbs_private *priv, u8 band); -int libertas_cmd_802_11d_domain_info(wlan_private * priv, +int lbs_cmd_802_11d_domain_info(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmdno, u16 cmdOption); -int libertas_ret_802_11d_domain_info(wlan_private * priv, +int lbs_ret_802_11d_domain_info(struct lbs_private *priv, struct cmd_ds_command *resp); struct bss_descriptor; -int libertas_parse_dnld_countryinfo_11d(wlan_private * priv, +int lbs_parse_dnld_countryinfo_11d(struct lbs_private *priv, struct bss_descriptor * bss); -int libertas_create_dnld_countryinfo_11d(wlan_private * priv); +int lbs_create_dnld_countryinfo_11d(struct lbs_private *priv); -#endif /* _WLAN_11D_ */ +#endif diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 0b133ce..d860fc3 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README @@ -195,45 +195,33 @@ setuserscan where [ARGS]: - chan=[chan#][band][mode] where band is [a,b,g] and mode is - blank for active or 'p' for passive bssid=xx:xx:xx:xx:xx:xx specify a BSSID filter for the scan ssid="[SSID]" specify a SSID filter for the scan keep=[0 or 1] keep the previous scan results (1), discard (0) dur=[scan time] time to scan for each channel in milliseconds - probes=[#] number of probe requests to send on each chan type=[1,2,3] BSS type: 1 (Infra), 2(Adhoc), 3(Any) - Any combination of the above arguments can be supplied on the command line. - If the chan token is absent, a full channel scan will be completed by - the driver. If the dur or probes tokens are absent, the driver default - setting will be used. The bssid and ssid fields, if blank, - will produce an unfiltered scan. The type field will default to 3 (Any) - and the keep field will default to 0 (Discard). + Any combination of the above arguments can be supplied on the command + line. If dur tokens are absent, the driver default setting will be used. + The bssid and ssid fields, if blank, will produce an unfiltered scan. + The type field will default to 3 (Any) and the keep field will default + to 0 (Discard). Examples: - 1) Perform an active scan on channels 1, 6, and 11 in the 'g' band: - echo "chan=1g,6g,11g" > setuserscan + 1) Perform a passive scan on all channels for 20 ms per channel: + echo "dur=20" > setuserscan - 2) Perform a passive scan on channel 11 for 20 ms: - echo "chan=11gp dur=20" > setuserscan + 2) Perform an active scan for a specific SSID: + echo "ssid="TestAP"" > setuserscan - 3) Perform an active scan on channels 1, 6, and 11; and a passive scan on - channel 36 in the 'a' band: - - echo "chan=1g,6g,11g,36ap" > setuserscan - - 4) Perform an active scan on channel 6 and 36 for a specific SSID: - echo "chan=6g,36a ssid="TestAP"" > setuserscan - - 5) Scan all available channels (B/G, A bands) for a specific BSSID, keep + 3) Scan all available channels (B/G, A bands) for a specific BSSID, keep the current scan table intact, update existing or append new scan data: echo "bssid=00:50:43:20:12:82 keep=1" > setuserscan - 6) Scan channel 6, for all infrastructure networks, sending two probe - requests. Keep the previous scan table intact. Update any duplicate - BSSID/SSID matches with the new scan data: - echo "chan=6g type=1 probes=2 keep=1" > setuserscan + 4) Scan for all infrastructure networks. + Keep the previous scan table intact. Update any duplicate BSSID/SSID + matches with the new scan data: + echo "type=1 keep=1" > setuserscan All entries in the scan table (not just the new scan data when keep=1) will be displayed upon completion by use of the getscantable ioctl. diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index b61b176..88da68e 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c @@ -14,34 +14,11 @@ static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) -{ - DECLARE_MAC_BUF(mac); - lbs_deb_assoc( - "#### Association Request: %s\n" - " flags: 0x%08lX\n" - " SSID: '%s'\n" - " channel: %d\n" - " band: %d\n" - " mode: %d\n" - " BSSID: %s\n" - " Encryption:%s%s%s\n" - " auth: %d\n", - extra, assoc_req->flags, - escape_essid(assoc_req->ssid, assoc_req->ssid_len), - assoc_req->channel, assoc_req->band, assoc_req->mode, - print_mac(mac, assoc_req->bssid), - assoc_req->secinfo.WPAenabled ? " WPA" : "", - assoc_req->secinfo.WPA2enabled ? " WPA2" : "", - assoc_req->secinfo.wep_enabled ? " WEP" : "", - assoc_req->secinfo.auth_mode); -} - -static int assoc_helper_essid(wlan_private *priv, +static int assoc_helper_essid(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct bss_descriptor * bss; int channel = -1; @@ -55,18 +32,17 @@ static int assoc_helper_essid(wlan_private *priv, if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) channel = assoc_req->channel; - lbs_deb_assoc("New SSID requested: '%s'\n", + lbs_deb_assoc("SSID '%s' requested\n", escape_essid(assoc_req->ssid, assoc_req->ssid_len)); if (assoc_req->mode == IW_MODE_INFRA) { - libertas_send_specific_ssid_scan(priv, assoc_req->ssid, + lbs_send_specific_ssid_scan(priv, assoc_req->ssid, assoc_req->ssid_len, 0); - bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, + bss = lbs_find_ssid_in_list(adapter, assoc_req->ssid, assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); if (bss != NULL) { - lbs_deb_assoc("SSID found in scan list, associating\n"); memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - ret = wlan_associate(priv, assoc_req); + ret = lbs_associate(priv, assoc_req); } else { lbs_deb_assoc("SSID not found; cannot associate\n"); } @@ -74,23 +50,23 @@ static int assoc_helper_essid(wlan_private *priv, /* Scan for the network, do not save previous results. Stale * scan data will cause us to join a non-existant adhoc network */ - libertas_send_specific_ssid_scan(priv, assoc_req->ssid, + lbs_send_specific_ssid_scan(priv, assoc_req->ssid, assoc_req->ssid_len, 1); /* Search for the requested SSID in the scan table */ - bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, + bss = lbs_find_ssid_in_list(adapter, assoc_req->ssid, assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel); if (bss != NULL) { lbs_deb_assoc("SSID found, will join\n"); memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); - libertas_join_adhoc_network(priv, assoc_req); + lbs_join_adhoc_network(priv, assoc_req); } else { /* else send START command */ lbs_deb_assoc("SSID not found, creating adhoc network\n"); memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, IW_ESSID_MAX_SIZE); assoc_req->bss.ssid_len = assoc_req->ssid_len; - libertas_start_adhoc_network(priv, assoc_req); + lbs_start_adhoc_network(priv, assoc_req); } } @@ -99,10 +75,10 @@ static int assoc_helper_essid(wlan_private *priv, } -static int assoc_helper_bssid(wlan_private *priv, +static int assoc_helper_bssid(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct bss_descriptor * bss; DECLARE_MAC_BUF(mac); @@ -111,7 +87,7 @@ static int assoc_helper_bssid(wlan_private *priv, print_mac(mac, assoc_req->bssid)); /* Search for index position in list for requested MAC */ - bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid, + bss = lbs_find_bssid_in_list(adapter, assoc_req->bssid, assoc_req->mode); if (bss == NULL) { lbs_deb_assoc("ASSOC: WAP: BSSID %s not found, " @@ -121,10 +97,10 @@ static int assoc_helper_bssid(wlan_private *priv, memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); if (assoc_req->mode == IW_MODE_INFRA) { - ret = wlan_associate(priv, assoc_req); - lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); + ret = lbs_associate(priv, assoc_req); + lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); } else if (assoc_req->mode == IW_MODE_ADHOC) { - libertas_join_adhoc_network(priv, assoc_req); + lbs_join_adhoc_network(priv, assoc_req); } out: @@ -133,11 +109,13 @@ out: } -static int assoc_helper_associate(wlan_private *priv, +static int assoc_helper_associate(struct lbs_private *priv, struct assoc_request * assoc_req) { int ret = 0, done = 0; + lbs_deb_enter(LBS_DEB_ASSOC); + /* If we're given and 'any' BSSID, try associating based on SSID */ if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { @@ -145,27 +123,22 @@ static int assoc_helper_associate(wlan_private *priv, && compare_ether_addr(bssid_off, assoc_req->bssid)) { ret = assoc_helper_bssid(priv, assoc_req); done = 1; - if (ret) { - lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); - } } } if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { ret = assoc_helper_essid(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); - } } + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } -static int assoc_helper_mode(wlan_private *priv, +static int assoc_helper_mode(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_ASSOC); @@ -175,12 +148,12 @@ static int assoc_helper_mode(wlan_private *priv, if (assoc_req->mode == IW_MODE_INFRA) { if (adapter->psstate != PS_STATE_FULL_POWER) - libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); - adapter->psmode = WLAN802_11POWERMODECAM; + lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); + adapter->psmode = LBS802_11POWERMODECAM; } adapter->mode = assoc_req->mode; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, 0, CMD_OPTION_WAITFORRSP, OID_802_11_INFRASTRUCTURE_MODE, @@ -192,26 +165,33 @@ done: } -static int update_channel(wlan_private * priv) +static int update_channel(struct lbs_private *priv) { + int ret; /* the channel in f/w could be out of sync, get the current channel */ - return libertas_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, + lbs_deb_enter(LBS_DEB_ASSOC); + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, CMD_OPT_802_11_RF_CHANNEL_GET, CMD_OPTION_WAITFORRSP, 0, NULL); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); + return ret; } -void libertas_sync_channel(struct work_struct *work) +void lbs_sync_channel(struct work_struct *work) { - wlan_private *priv = container_of(work, wlan_private, sync_channel); + struct lbs_private *priv = container_of(work, struct lbs_private, + sync_channel); + lbs_deb_enter(LBS_DEB_ASSOC); if (update_channel(priv) != 0) lbs_pr_info("Channel synchronization failed."); + lbs_deb_leave(LBS_DEB_ASSOC); } -static int assoc_helper_channel(wlan_private *priv, +static int assoc_helper_channel(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_ASSOC); @@ -227,7 +207,7 @@ static int assoc_helper_channel(wlan_private *priv, lbs_deb_assoc("ASSOC: channel: %d -> %d\n", adapter->curbssparams.channel, assoc_req->channel); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_CHANNEL, CMD_OPT_802_11_RF_CHANNEL_SET, CMD_OPTION_WAITFORRSP, 0, &assoc_req->channel); if (ret < 0) { @@ -263,10 +243,10 @@ done: } -static int assoc_helper_wep_keys(wlan_private *priv, +static int assoc_helper_wep_keys(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int i; int ret = 0; @@ -277,13 +257,13 @@ static int assoc_helper_wep_keys(wlan_private *priv, || assoc_req->wep_keys[1].len || assoc_req->wep_keys[2].len || assoc_req->wep_keys[3].len) { - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SET_WEP, CMD_ACT_ADD, CMD_OPTION_WAITFORRSP, 0, assoc_req); } else { - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SET_WEP, CMD_ACT_REMOVE, CMD_OPTION_WAITFORRSP, @@ -298,7 +278,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, adapter->currentpacketfilter |= CMD_ACT_MAC_WEP_ENABLE; else adapter->currentpacketfilter &= ~CMD_ACT_MAC_WEP_ENABLE; - ret = libertas_set_mac_packet_filter(priv); + ret = lbs_set_mac_packet_filter(priv); if (ret) goto out; @@ -318,10 +298,10 @@ out: return ret; } -static int assoc_helper_secinfo(wlan_private *priv, +static int assoc_helper_secinfo(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; u32 do_wpa; u32 rsn = 0; @@ -329,9 +309,9 @@ static int assoc_helper_secinfo(wlan_private *priv, lbs_deb_enter(LBS_DEB_ASSOC); memcpy(&adapter->secinfo, &assoc_req->secinfo, - sizeof(struct wlan_802_11_security)); + sizeof(struct lbs_802_11_security)); - ret = libertas_set_mac_packet_filter(priv); + ret = lbs_set_mac_packet_filter(priv); if (ret) goto out; @@ -341,7 +321,7 @@ static int assoc_helper_secinfo(wlan_private *priv, */ /* Get RSN enabled/disabled */ - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_ENABLE_RSN, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, @@ -358,7 +338,7 @@ static int assoc_helper_secinfo(wlan_private *priv, /* Set RSN enabled/disabled */ rsn = do_wpa; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_ENABLE_RSN, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, @@ -370,7 +350,7 @@ out: } -static int assoc_helper_wpa_keys(wlan_private *priv, +static int assoc_helper_wpa_keys(struct lbs_private *priv, struct assoc_request * assoc_req) { int ret = 0; @@ -385,7 +365,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, if (test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_KEY_MATERIAL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, @@ -399,7 +379,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags)) { clear_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_KEY_MATERIAL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, @@ -413,10 +393,10 @@ out: } -static int assoc_helper_wpa_ie(wlan_private *priv, +static int assoc_helper_wpa_ie(struct lbs_private *priv, struct assoc_request * assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_ASSOC); @@ -434,54 +414,67 @@ static int assoc_helper_wpa_ie(wlan_private *priv, } -static int should_deauth_infrastructure(wlan_adapter *adapter, +static int should_deauth_infrastructure(struct lbs_adapter *adapter, struct assoc_request * assoc_req) { - if (adapter->connect_status != LIBERTAS_CONNECTED) + int ret = 0; + + lbs_deb_enter(LBS_DEB_ASSOC); + + if (adapter->connect_status != LBS_CONNECTED) return 0; if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to new SSID in " - " configuration request.\n"); - return 1; + lbs_deb_assoc("Deauthenticating due to new SSID\n"); + ret = 1; + goto out; } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { - lbs_deb_assoc("Deauthenticating due to updated security " - "info in configuration request.\n"); - return 1; + lbs_deb_assoc("Deauthenticating due to new security\n"); + ret = 1; + goto out; } } if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to new BSSID in " - " configuration request.\n"); - return 1; + lbs_deb_assoc("Deauthenticating due to new BSSID\n"); + ret = 1; + goto out; } if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { - lbs_deb_assoc("Deauthenticating due to channel switch.\n"); - return 1; + lbs_deb_assoc("Deauthenticating due to channel switch\n"); + ret = 1; + goto out; } /* FIXME: deal with 'auto' mode somehow */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { - if (assoc_req->mode != IW_MODE_INFRA) - return 1; + if (assoc_req->mode != IW_MODE_INFRA) { + lbs_deb_assoc("Deauthenticating due to leaving " + "infra mode\n"); + ret = 1; + goto out; + } } +out: + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return 0; } -static int should_stop_adhoc(wlan_adapter *adapter, +static int should_stop_adhoc(struct lbs_adapter *adapter, struct assoc_request * assoc_req) { - if (adapter->connect_status != LIBERTAS_CONNECTED) + lbs_deb_enter(LBS_DEB_ASSOC); + + if (adapter->connect_status != LBS_CONNECTED) return 0; - if (libertas_ssid_cmp(adapter->curbssparams.ssid, + if (lbs_ssid_cmp(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len, assoc_req->ssid, assoc_req->ssid_len) != 0) return 1; @@ -497,14 +490,16 @@ static int should_stop_adhoc(wlan_adapter *adapter, return 1; } + lbs_deb_leave(LBS_DEB_ASSOC); return 0; } -void libertas_association_worker(struct work_struct *work) +void lbs_association_worker(struct work_struct *work) { - wlan_private *priv = container_of(work, wlan_private, assoc_work.work); - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = container_of(work, struct lbs_private, + assoc_work.work); + struct lbs_adapter *adapter = priv->adapter; struct assoc_request * assoc_req = NULL; int ret = 0; int find_any_ssid = 0; @@ -521,7 +516,24 @@ void libertas_association_worker(struct work_struct *work) if (!assoc_req) goto done; - print_assoc_req(__func__, assoc_req); + lbs_deb_assoc( + "Association Request:\n" + " flags: 0x%08lx\n" + " SSID: '%s'\n" + " chann: %d\n" + " band: %d\n" + " mode: %d\n" + " BSSID: %s\n" + " secinfo: %s%s%s\n" + " auth_mode: %d\n", + assoc_req->flags, + escape_essid(assoc_req->ssid, assoc_req->ssid_len), + assoc_req->channel, assoc_req->band, assoc_req->mode, + print_mac(mac, assoc_req->bssid), + assoc_req->secinfo.WPAenabled ? " WPA" : "", + assoc_req->secinfo.WPA2enabled ? " WPA2" : "", + assoc_req->secinfo.wep_enabled ? " WEP" : "", + assoc_req->secinfo.auth_mode); /* If 'any' SSID was specified, find an SSID to associate with */ if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) @@ -538,7 +550,7 @@ void libertas_association_worker(struct work_struct *work) if (find_any_ssid) { u8 new_mode; - ret = libertas_find_best_network_ssid(priv, assoc_req->ssid, + ret = lbs_find_best_network_ssid(priv, assoc_req->ssid, &assoc_req->ssid_len, assoc_req->mode, &new_mode); if (ret) { lbs_deb_assoc("Could not find best network\n"); @@ -559,7 +571,7 @@ void libertas_association_worker(struct work_struct *work) */ if (adapter->mode == IW_MODE_INFRA) { if (should_deauth_infrastructure(adapter, assoc_req)) { - ret = libertas_send_deauthentication(priv); + ret = lbs_send_deauthentication(priv); if (ret) { lbs_deb_assoc("Deauthentication due to new " "configuration request failed: %d\n", @@ -568,7 +580,7 @@ void libertas_association_worker(struct work_struct *work) } } else if (adapter->mode == IW_MODE_ADHOC) { if (should_stop_adhoc(adapter, assoc_req)) { - ret = libertas_stop_adhoc_network(priv); + ret = lbs_stop_adhoc_network(priv); if (ret) { lbs_deb_assoc("Teardown of AdHoc network due to " "new configuration request failed: %d\n", @@ -581,58 +593,40 @@ void libertas_association_worker(struct work_struct *work) /* Send the various configuration bits to the firmware */ if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { ret = assoc_helper_mode(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { ret = assoc_helper_channel(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } if ( test_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags) || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { ret = assoc_helper_wep_keys(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { ret = assoc_helper_secinfo(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { ret = assoc_helper_wpa_ie(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } if (test_bit(ASSOC_FLAG_WPA_MCAST_KEY, &assoc_req->flags) || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { ret = assoc_helper_wpa_keys(priv, assoc_req); - if (ret) { - lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", - __LINE__, ret); + if (ret) goto out; - } } /* SSID/BSSID should be the _last_ config option set, because they @@ -644,28 +638,27 @@ void libertas_association_worker(struct work_struct *work) ret = assoc_helper_associate(priv, assoc_req); if (ret) { - lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n", + lbs_deb_assoc("ASSOC: association unsuccessful: %d\n", ret); success = 0; } - if (adapter->connect_status != LIBERTAS_CONNECTED) { - lbs_deb_assoc("ASSOC: association attempt unsuccessful, " - "not connected.\n"); + if (adapter->connect_status != LBS_CONNECTED) { + lbs_deb_assoc("ASSOC: association unsuccessful, " + "not connected\n"); success = 0; } if (success) { - lbs_deb_assoc("ASSOC: association attempt successful. " - "Associated to '%s' (%s)\n", + lbs_deb_assoc("ASSOC: associated to '%s', %s\n", escape_essid(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len), print_mac(mac, adapter->curbssparams.bssid)); - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, CMD_OPTION_WAITFORRSP, 0, NULL); - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, CMD_OPTION_WAITFORRSP, 0, NULL); } else { @@ -692,10 +685,11 @@ done: /* * Caller MUST hold any necessary locks */ -struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) +struct assoc_request *lbs_get_association_request(struct lbs_adapter *adapter) { struct assoc_request * assoc_req; + lbs_deb_enter(LBS_DEB_ASSOC); if (!adapter->pending_assoc_req) { adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); @@ -753,7 +747,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) if (!test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { memcpy(&assoc_req->secinfo, &adapter->secinfo, - sizeof(struct wlan_802_11_security)); + sizeof(struct lbs_802_11_security)); } if (!test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { @@ -762,7 +756,6 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) assoc_req->wpa_ie_len = adapter->wpa_ie_len; } - print_assoc_req(__func__, assoc_req); - + lbs_deb_leave(LBS_DEB_ASSOC); return assoc_req; } diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h index e09b749..fad00ae 100644 --- a/drivers/net/wireless/libertas/assoc.h +++ b/drivers/net/wireless/libertas/assoc.h @@ -1,32 +1,12 @@ /* Copyright (C) 2006, Red Hat, Inc. */ -#ifndef _WLAN_ASSOC_H_ -#define _WLAN_ASSOC_H_ +#ifndef _LBS_ASSOC_H_ +#define _LBS_ASSOC_H_ #include "dev.h" -void libertas_association_worker(struct work_struct *work); +void lbs_association_worker(struct work_struct *work); +struct assoc_request *lbs_get_association_request(struct lbs_adapter *adapter); +void lbs_sync_channel(struct work_struct *work); -struct assoc_request * wlan_get_association_request(wlan_adapter *adapter); - -void libertas_sync_channel(struct work_struct *work); - -#define ASSOC_DELAY (HZ / 2) -static inline void wlan_postpone_association_work(wlan_private *priv) -{ - if (priv->adapter->surpriseremoved) - return; - cancel_delayed_work(&priv->assoc_work); - queue_delayed_work(priv->work_thread, &priv->assoc_work, ASSOC_DELAY); -} - -static inline void wlan_cancel_association_work(wlan_private *priv) -{ - cancel_delayed_work(&priv->assoc_work); - if (priv->adapter->pending_assoc_req) { - kfree(priv->adapter->pending_assoc_req); - priv->adapter->pending_assoc_req = NULL; - } -} - -#endif /* _WLAN_ASSOC_H */ +#endif /* _LBS_ASSOC_H */ diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index be5cfd8..d98bec9 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -37,7 +37,7 @@ static u8 is_command_allowed_in_ps(__le16 command) return 0; } -static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd) +static int lbs_cmd_hw_spec(struct lbs_private *priv, struct cmd_ds_command *cmd) { struct cmd_ds_get_hw_spec *hwspec = &cmd->params.hwspec; @@ -51,7 +51,7 @@ static int wlan_cmd_hw_spec(wlan_private * priv, struct cmd_ds_command *cmd) return 0; } -static int wlan_cmd_802_11_ps_mode(wlan_private * priv, +static int lbs_cmd_802_11_ps_mode(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { @@ -90,7 +90,7 @@ static int wlan_cmd_802_11_ps_mode(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, +static int lbs_cmd_802_11_inactivity_timeout(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -114,11 +114,11 @@ static int wlan_cmd_802_11_inactivity_timeout(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_sleep_params(wlan_private * priv, +static int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_sleep_params *sp = &cmd->params.sleep_params; lbs_deb_enter(LBS_DEB_CMD); @@ -145,13 +145,13 @@ static int wlan_cmd_802_11_sleep_params(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_set_wep(wlan_private * priv, +static int lbs_cmd_802_11_set_wep(struct lbs_private *priv, struct cmd_ds_command *cmd, u32 cmd_act, void * pdata_buf) { struct cmd_ds_802_11_set_wep *wep = &cmd->params.wep; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct assoc_request * assoc_req = pdata_buf; @@ -219,7 +219,7 @@ done: return ret; } -static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, +static int lbs_cmd_802_11_enable_rsn(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void * pdata_buf) @@ -246,6 +246,52 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, } +static ssize_t lbs_tlv_size(const u8 *tlv, u16 size) +{ + ssize_t pos = 0; + struct mrvlietypesheader *tlv_h; + while (pos < size) { + u16 length; + tlv_h = (struct mrvlietypesheader *) tlv; + if (tlv_h->len == 0) + return pos; + length = le16_to_cpu(tlv_h->len) + + sizeof(struct mrvlietypesheader); + pos += length; + tlv += length; + } + return pos; +} + + +static void lbs_cmd_802_11_subscribe_event(struct lbs_private *priv, + struct cmd_ds_command *cmd, u16 cmd_action, + void *pdata_buf) +{ + struct cmd_ds_802_11_subscribe_event *events = + (struct cmd_ds_802_11_subscribe_event *) pdata_buf; + + /* pdata_buf points to a struct cmd_ds_802_11_subscribe_event and room + * for various Marvell TLVs */ + + lbs_deb_enter(LBS_DEB_CMD); + + cmd->size = cpu_to_le16(sizeof(*events) + - sizeof(events->tlv) + + S_DS_GEN); + cmd->params.subscribe_event.action = cpu_to_le16(cmd_action); + if (cmd_action == CMD_ACT_GET) { + cmd->params.subscribe_event.events = 0; + } else { + ssize_t sz = lbs_tlv_size(events->tlv, sizeof(events->tlv)); + cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sz); + cmd->params.subscribe_event.events = events->events; + memcpy(cmd->params.subscribe_event.tlv, events->tlv, sz); + } + + lbs_deb_leave(LBS_DEB_CMD); +} + static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, struct enc_key * pkey) { @@ -272,7 +318,7 @@ static void set_one_wpa_key(struct MrvlIEtype_keyParamSet * pkeyparamset, lbs_deb_leave(LBS_DEB_CMD); } -static int wlan_cmd_802_11_key_material(wlan_private * priv, +static int lbs_cmd_802_11_key_material(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, u32 cmd_oid, void *pdata_buf) @@ -319,7 +365,7 @@ done: return ret; } -static int wlan_cmd_802_11_reset(wlan_private * priv, +static int lbs_cmd_802_11_reset(struct lbs_private *priv, struct cmd_ds_command *cmd, int cmd_action) { struct cmd_ds_802_11_reset *reset = &cmd->params.reset; @@ -334,7 +380,7 @@ static int wlan_cmd_802_11_reset(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_get_log(wlan_private * priv, +static int lbs_cmd_802_11_get_log(struct lbs_private *priv, struct cmd_ds_command *cmd) { lbs_deb_enter(LBS_DEB_CMD); @@ -346,7 +392,7 @@ static int wlan_cmd_802_11_get_log(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_get_stat(wlan_private * priv, +static int lbs_cmd_802_11_get_stat(struct lbs_private *priv, struct cmd_ds_command *cmd) { lbs_deb_enter(LBS_DEB_CMD); @@ -358,13 +404,13 @@ static int wlan_cmd_802_11_get_stat(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, +static int lbs_cmd_802_11_snmp_mib(struct lbs_private *priv, struct cmd_ds_command *cmd, int cmd_action, int cmd_oid, void *pdata_buf) { struct cmd_ds_802_11_snmp_mib *pSNMPMIB = &cmd->params.smib; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u8 ucTemp; lbs_deb_enter(LBS_DEB_CMD); @@ -479,11 +525,11 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_radio_control(wlan_private * priv, +static int lbs_cmd_802_11_radio_control(struct lbs_private *priv, struct cmd_ds_command *cmd, int cmd_action) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_radio_control *pradiocontrol = &cmd->params.radio; lbs_deb_enter(LBS_DEB_CMD); @@ -519,7 +565,7 @@ static int wlan_cmd_802_11_radio_control(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, +static int lbs_cmd_802_11_rf_tx_power(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -563,7 +609,7 @@ static int wlan_cmd_802_11_rf_tx_power(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_monitor_mode(wlan_private * priv, +static int lbs_cmd_802_11_monitor_mode(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -583,13 +629,13 @@ static int wlan_cmd_802_11_monitor_mode(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv, +static int lbs_cmd_802_11_rate_adapt_rateset(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { struct cmd_ds_802_11_rate_adapt_rateset *rateadapt = &cmd->params.rateset; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); cmd->size = @@ -605,12 +651,12 @@ static int wlan_cmd_802_11_rate_adapt_rateset(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_data_rate(wlan_private * priv, +static int lbs_cmd_802_11_data_rate(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { struct cmd_ds_802_11_data_rate *pdatarate = &cmd->params.drate; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -621,7 +667,7 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, pdatarate->action = cpu_to_le16(cmd_action); if (cmd_action == CMD_ACT_SET_TX_FIX_RATE) { - pdatarate->rates[0] = libertas_data_rate_to_fw_index(adapter->cur_rate); + pdatarate->rates[0] = lbs_data_rate_to_fw_index(adapter->cur_rate); lbs_deb_cmd("DATA_RATE: set fixed 0x%02X\n", adapter->cur_rate); } else if (cmd_action == CMD_ACT_SET_TX_AUTO) { @@ -632,12 +678,12 @@ static int wlan_cmd_802_11_data_rate(wlan_private * priv, return 0; } -static int wlan_cmd_mac_multicast_adr(wlan_private * priv, +static int lbs_cmd_mac_multicast_adr(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { struct cmd_ds_mac_multicast_adr *pMCastAdr = &cmd->params.madr; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); cmd->size = cpu_to_le16(sizeof(struct cmd_ds_mac_multicast_adr) + @@ -655,7 +701,7 @@ static int wlan_cmd_mac_multicast_adr(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_rf_channel(wlan_private * priv, +static int lbs_cmd_802_11_rf_channel(struct lbs_private *priv, struct cmd_ds_command *cmd, int option, void *pdata_buf) { @@ -676,10 +722,10 @@ static int wlan_cmd_802_11_rf_channel(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_rssi(wlan_private * priv, +static int lbs_cmd_802_11_rssi(struct lbs_private *priv, struct cmd_ds_command *cmd) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_RSSI); @@ -698,15 +744,15 @@ static int wlan_cmd_802_11_rssi(wlan_private * priv, return 0; } -static int wlan_cmd_reg_access(wlan_private * priv, +static int lbs_cmd_reg_access(struct lbs_private *priv, struct cmd_ds_command *cmdptr, u8 cmd_action, void *pdata_buf) { - struct wlan_offset_value *offval; + struct lbs_offset_value *offval; lbs_deb_enter(LBS_DEB_CMD); - offval = (struct wlan_offset_value *)pdata_buf; + offval = (struct lbs_offset_value *)pdata_buf; switch (cmdptr->command) { case CMD_MAC_REG_ACCESS: @@ -773,11 +819,11 @@ static int wlan_cmd_reg_access(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_mac_address(wlan_private * priv, +static int lbs_cmd_802_11_mac_address(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); cmd->command = cpu_to_le16(CMD_802_11_MAC_ADDRESS); @@ -797,11 +843,11 @@ static int wlan_cmd_802_11_mac_address(wlan_private * priv, return 0; } -static int wlan_cmd_802_11_eeprom_access(wlan_private * priv, +static int lbs_cmd_802_11_eeprom_access(struct lbs_private *priv, struct cmd_ds_command *cmd, int cmd_action, void *pdata_buf) { - struct wlan_ioctl_regrdwr *ea = pdata_buf; + struct lbs_ioctl_regrdwr *ea = pdata_buf; lbs_deb_enter(LBS_DEB_CMD); @@ -819,7 +865,7 @@ static int wlan_cmd_802_11_eeprom_access(wlan_private * priv, return 0; } -static int wlan_cmd_bt_access(wlan_private * priv, +static int lbs_cmd_bt_access(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -857,7 +903,7 @@ static int wlan_cmd_bt_access(wlan_private * priv, return 0; } -static int wlan_cmd_fwt_access(wlan_private * priv, +static int lbs_cmd_fwt_access(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -879,7 +925,7 @@ static int wlan_cmd_fwt_access(wlan_private * priv, return 0; } -static int wlan_cmd_mesh_access(wlan_private * priv, +static int lbs_cmd_mesh_access(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -901,7 +947,29 @@ static int wlan_cmd_mesh_access(wlan_private * priv, return 0; } -static int wlan_cmd_set_boot2_ver(wlan_private * priv, +static int lbs_cmd_bcn_ctrl(struct lbs_private * priv, + struct cmd_ds_command *cmd, + u16 cmd_action) +{ + struct cmd_ds_802_11_beacon_control + *bcn_ctrl = &cmd->params.bcn_ctrl; + struct lbs_adapter *adapter = priv->adapter; + + lbs_deb_enter(LBS_DEB_CMD); + cmd->size = + cpu_to_le16(sizeof(struct cmd_ds_802_11_beacon_control) + + S_DS_GEN); + cmd->command = cpu_to_le16(CMD_802_11_BEACON_CTRL); + + bcn_ctrl->action = cpu_to_le16(cmd_action); + bcn_ctrl->beacon_enable = cpu_to_le16(adapter->beacon_enable); + bcn_ctrl->beacon_period = cpu_to_le16(adapter->beacon_period); + + lbs_deb_leave(LBS_DEB_CMD); + return 0; +} + +static int lbs_cmd_set_boot2_ver(struct lbs_private *priv, struct cmd_ds_command *cmd, u16 cmd_action, void *pdata_buf) { @@ -913,10 +981,12 @@ static int wlan_cmd_set_boot2_ver(wlan_private * priv, } /* - * Note: NEVER use libertas_queue_cmd() with addtail==0 other than for + * Note: NEVER use lbs_queue_cmd() with addtail==0 other than for * the command timer, because it does not account for queued commands. */ -void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail) +void lbs_queue_cmd(struct lbs_adapter *adapter, + struct cmd_ctrl_node *cmdnode, + u8 addtail) { unsigned long flags; struct cmd_ds_command *cmdptr; @@ -968,12 +1038,12 @@ done: * For now - we are not performing the endian conversion the second time - but * for PS and DEEP_SLEEP we need to worry */ -static int DownloadcommandToStation(wlan_private * priv, +static int DownloadcommandToStation(struct lbs_private *priv, struct cmd_ctrl_node *cmdnode) { unsigned long flags; struct cmd_ds_command *cmdptr; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = -1; u16 cmdsize; u16 command; @@ -990,7 +1060,7 @@ static int DownloadcommandToStation(wlan_private * priv, spin_lock_irqsave(&adapter->driver_lock, flags); if (!cmdptr || !cmdptr->size) { lbs_deb_host("DNLD_CMD: cmdptr is NULL or zero\n"); - __libertas_cleanup_and_insert_cmd(priv, cmdnode); + __lbs_cleanup_and_insert_cmd(priv, cmdnode); spin_unlock_irqrestore(&adapter->driver_lock, flags); goto done; } @@ -1015,7 +1085,7 @@ static int DownloadcommandToStation(wlan_private * priv, lbs_deb_host("DNLD_CMD: hw_host_to_card failed\n"); spin_lock_irqsave(&adapter->driver_lock, flags); adapter->cur_cmd_retcode = ret; - __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -1038,7 +1108,7 @@ done: return ret; } -static int wlan_cmd_mac_control(wlan_private * priv, +static int lbs_cmd_mac_control(struct lbs_private *priv, struct cmd_ds_command *cmd) { struct cmd_ds_mac_control *mac = &cmd->params.macctrl; @@ -1060,9 +1130,10 @@ static int wlan_cmd_mac_control(wlan_private * priv, * This function inserts command node to cmdfreeq * after cleans it. Requires adapter->driver_lock held. */ -void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd) +void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv, + struct cmd_ctrl_node *ptempcmd) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; if (!ptempcmd) return; @@ -1071,22 +1142,23 @@ void __libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node list_add_tail((struct list_head *)ptempcmd, &adapter->cmdfreeq); } -static void libertas_cleanup_and_insert_cmd(wlan_private * priv, struct cmd_ctrl_node *ptempcmd) +static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv, + struct cmd_ctrl_node *ptempcmd) { unsigned long flags; spin_lock_irqsave(&priv->adapter->driver_lock, flags); - __libertas_cleanup_and_insert_cmd(priv, ptempcmd); + __lbs_cleanup_and_insert_cmd(priv, ptempcmd); spin_unlock_irqrestore(&priv->adapter->driver_lock, flags); } -int libertas_set_radio_control(wlan_private * priv) +int lbs_set_radio_control(struct lbs_private *priv) { int ret = 0; lbs_deb_enter(LBS_DEB_CMD); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RADIO_CONTROL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -1098,14 +1170,14 @@ int libertas_set_radio_control(wlan_private * priv) return ret; } -int libertas_set_mac_packet_filter(wlan_private * priv) +int lbs_set_mac_packet_filter(struct lbs_private *priv) { int ret = 0; lbs_deb_enter(LBS_DEB_CMD); /* Send MAC control command to station */ - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_MAC_CONTROL, 0, 0, 0, NULL); lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); @@ -1115,7 +1187,7 @@ int libertas_set_mac_packet_filter(wlan_private * priv) /** * @brief This function prepare the command before send to firmware. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param cmd_no command number * @param cmd_action command action: GET or SET * @param wait_option wait option: wait response or not @@ -1123,13 +1195,13 @@ int libertas_set_mac_packet_filter(wlan_private * priv) * @param pdata_buf A pointer to informaion buffer * @return 0 or -1 */ -int libertas_prepare_and_send_command(wlan_private * priv, +int lbs_prepare_and_send_command(struct lbs_private *priv, u16 cmd_no, u16 cmd_action, u16 wait_option, u32 cmd_oid, void *pdata_buf) { int ret = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ctrl_node *cmdnode; struct cmd_ds_command *cmdptr; unsigned long flags; @@ -1148,7 +1220,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, goto done; } - cmdnode = libertas_get_free_cmd_ctrl_node(priv); + cmdnode = lbs_get_free_cmd_ctrl_node(priv); if (cmdnode == NULL) { lbs_deb_host("PREP_CMD: cmdnode is NULL\n"); @@ -1159,7 +1231,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, goto done; } - libertas_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf); + lbs_set_cmd_ctrl_node(priv, cmdnode, cmd_oid, wait_option, pdata_buf); cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr; @@ -1167,7 +1239,7 @@ int libertas_prepare_and_send_command(wlan_private * priv, if (!cmdptr) { lbs_deb_host("PREP_CMD: cmdptr is NULL\n"); - libertas_cleanup_and_insert_cmd(priv, cmdnode); + lbs_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; } @@ -1181,116 +1253,116 @@ int libertas_prepare_and_send_command(wlan_private * priv, switch (cmd_no) { case CMD_GET_HW_SPEC: - ret = wlan_cmd_hw_spec(priv, cmdptr); + ret = lbs_cmd_hw_spec(priv, cmdptr); break; case CMD_802_11_PS_MODE: - ret = wlan_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_ps_mode(priv, cmdptr, cmd_action); break; case CMD_802_11_SCAN: - ret = libertas_cmd_80211_scan(priv, cmdptr, pdata_buf); + ret = lbs_cmd_80211_scan(priv, cmdptr, pdata_buf); break; case CMD_MAC_CONTROL: - ret = wlan_cmd_mac_control(priv, cmdptr); + ret = lbs_cmd_mac_control(priv, cmdptr); break; case CMD_802_11_ASSOCIATE: case CMD_802_11_REASSOCIATE: - ret = libertas_cmd_80211_associate(priv, cmdptr, pdata_buf); + ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf); break; case CMD_802_11_DEAUTHENTICATE: - ret = libertas_cmd_80211_deauthenticate(priv, cmdptr); + ret = lbs_cmd_80211_deauthenticate(priv, cmdptr); break; case CMD_802_11_SET_WEP: - ret = wlan_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_802_11_set_wep(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_AD_HOC_START: - ret = libertas_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf); + ret = lbs_cmd_80211_ad_hoc_start(priv, cmdptr, pdata_buf); break; case CMD_CODE_DNLD: break; case CMD_802_11_RESET: - ret = wlan_cmd_802_11_reset(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_reset(priv, cmdptr, cmd_action); break; case CMD_802_11_GET_LOG: - ret = wlan_cmd_802_11_get_log(priv, cmdptr); + ret = lbs_cmd_802_11_get_log(priv, cmdptr); break; case CMD_802_11_AUTHENTICATE: - ret = libertas_cmd_80211_authenticate(priv, cmdptr, pdata_buf); + ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf); break; case CMD_802_11_GET_STAT: - ret = wlan_cmd_802_11_get_stat(priv, cmdptr); + ret = lbs_cmd_802_11_get_stat(priv, cmdptr); break; case CMD_802_11_SNMP_MIB: - ret = wlan_cmd_802_11_snmp_mib(priv, cmdptr, + ret = lbs_cmd_802_11_snmp_mib(priv, cmdptr, cmd_action, cmd_oid, pdata_buf); break; case CMD_MAC_REG_ACCESS: case CMD_BBP_REG_ACCESS: case CMD_RF_REG_ACCESS: - ret = wlan_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_reg_access(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_RF_CHANNEL: - ret = wlan_cmd_802_11_rf_channel(priv, cmdptr, + ret = lbs_cmd_802_11_rf_channel(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_RF_TX_POWER: - ret = wlan_cmd_802_11_rf_tx_power(priv, cmdptr, + ret = lbs_cmd_802_11_rf_tx_power(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_RADIO_CONTROL: - ret = wlan_cmd_802_11_radio_control(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_radio_control(priv, cmdptr, cmd_action); break; case CMD_802_11_DATA_RATE: - ret = wlan_cmd_802_11_data_rate(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_data_rate(priv, cmdptr, cmd_action); break; case CMD_802_11_RATE_ADAPT_RATESET: - ret = wlan_cmd_802_11_rate_adapt_rateset(priv, + ret = lbs_cmd_802_11_rate_adapt_rateset(priv, cmdptr, cmd_action); break; case CMD_MAC_MULTICAST_ADR: - ret = wlan_cmd_mac_multicast_adr(priv, cmdptr, cmd_action); + ret = lbs_cmd_mac_multicast_adr(priv, cmdptr, cmd_action); break; case CMD_802_11_MONITOR_MODE: - ret = wlan_cmd_802_11_monitor_mode(priv, cmdptr, + ret = lbs_cmd_802_11_monitor_mode(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_AD_HOC_JOIN: - ret = libertas_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf); + ret = lbs_cmd_80211_ad_hoc_join(priv, cmdptr, pdata_buf); break; case CMD_802_11_RSSI: - ret = wlan_cmd_802_11_rssi(priv, cmdptr); + ret = lbs_cmd_802_11_rssi(priv, cmdptr); break; case CMD_802_11_AD_HOC_STOP: - ret = libertas_cmd_80211_ad_hoc_stop(priv, cmdptr); + ret = lbs_cmd_80211_ad_hoc_stop(priv, cmdptr); break; case CMD_802_11_ENABLE_RSN: - ret = wlan_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action, + ret = lbs_cmd_802_11_enable_rsn(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_802_11_KEY_MATERIAL: - ret = wlan_cmd_802_11_key_material(priv, cmdptr, cmd_action, + ret = lbs_cmd_802_11_key_material(priv, cmdptr, cmd_action, cmd_oid, pdata_buf); break; @@ -1300,11 +1372,11 @@ int libertas_prepare_and_send_command(wlan_private * priv, break; case CMD_802_11_MAC_ADDRESS: - ret = wlan_cmd_802_11_mac_address(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_mac_address(priv, cmdptr, cmd_action); break; case CMD_802_11_EEPROM_ACCESS: - ret = wlan_cmd_802_11_eeprom_access(priv, cmdptr, + ret = lbs_cmd_802_11_eeprom_access(priv, cmdptr, cmd_action, pdata_buf); break; @@ -1322,17 +1394,17 @@ int libertas_prepare_and_send_command(wlan_private * priv, goto done; case CMD_802_11D_DOMAIN_INFO: - ret = libertas_cmd_802_11d_domain_info(priv, cmdptr, + ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_no, cmd_action); break; case CMD_802_11_SLEEP_PARAMS: - ret = wlan_cmd_802_11_sleep_params(priv, cmdptr, cmd_action); + ret = lbs_cmd_802_11_sleep_params(priv, cmdptr, cmd_action); break; case CMD_802_11_INACTIVITY_TIMEOUT: - ret = wlan_cmd_802_11_inactivity_timeout(priv, cmdptr, + ret = lbs_cmd_802_11_inactivity_timeout(priv, cmdptr, cmd_action, pdata_buf); - libertas_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf); + lbs_set_cmd_ctrl_node(priv, cmdnode, 0, 0, pdata_buf); break; case CMD_802_11_TPC_CFG: @@ -1368,6 +1440,10 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; break; } + case CMD_802_11_SUBSCRIBE_EVENT: + lbs_cmd_802_11_subscribe_event(priv, cmdptr, + cmd_action, pdata_buf); + break; case CMD_802_11_PWR_CFG: cmdptr->command = cpu_to_le16(CMD_802_11_PWR_CFG); cmdptr->size = @@ -1379,19 +1455,19 @@ int libertas_prepare_and_send_command(wlan_private * priv, ret = 0; break; case CMD_BT_ACCESS: - ret = wlan_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_bt_access(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_FWT_ACCESS: - ret = wlan_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_fwt_access(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_MESH_ACCESS: - ret = wlan_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_mesh_access(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_SET_BOOT2_VER: - ret = wlan_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf); + ret = lbs_cmd_set_boot2_ver(priv, cmdptr, cmd_action, pdata_buf); break; case CMD_GET_TSF: @@ -1400,6 +1476,9 @@ int libertas_prepare_and_send_command(wlan_private * priv, S_DS_GEN); ret = 0; break; + case CMD_802_11_BEACON_CTRL: + ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action); + break; default: lbs_deb_host("PREP_CMD: unknown command 0x%04x\n", cmd_no); ret = -1; @@ -1409,14 +1488,14 @@ int libertas_prepare_and_send_command(wlan_private * priv, /* return error, since the command preparation failed */ if (ret != 0) { lbs_deb_host("PREP_CMD: command preparation failed\n"); - libertas_cleanup_and_insert_cmd(priv, cmdnode); + lbs_cleanup_and_insert_cmd(priv, cmdnode); ret = -1; goto done; } cmdnode->cmdwaitqwoken = 0; - libertas_queue_cmd(adapter, cmdnode, 1); + lbs_queue_cmd(adapter, cmdnode, 1); wake_up_interruptible(&priv->waitq); if (wait_option & CMD_OPTION_WAITFORRSP) { @@ -1439,23 +1518,23 @@ done: lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_prepare_and_send_command); +EXPORT_SYMBOL_GPL(lbs_prepare_and_send_command); /** * @brief This function allocates the command buffer and link * it to command free queue. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return 0 or -1 */ -int libertas_allocate_cmd_buffer(wlan_private * priv) +int lbs_allocate_cmd_buffer(struct lbs_private *priv) { int ret = 0; u32 ulbufsize; u32 i; struct cmd_ctrl_node *tempcmd_array; u8 *ptempvirtualaddr; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_HOST); @@ -1484,7 +1563,7 @@ int libertas_allocate_cmd_buffer(wlan_private * priv) for (i = 0; i < MRVDRV_NUM_OF_CMD_BUFFER; i++) { init_waitqueue_head(&tempcmd_array[i].cmdwait_q); - libertas_cleanup_and_insert_cmd(priv, &tempcmd_array[i]); + lbs_cleanup_and_insert_cmd(priv, &tempcmd_array[i]); } ret = 0; @@ -1497,15 +1576,15 @@ done: /** * @brief This function frees the command buffer. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return 0 or -1 */ -int libertas_free_cmd_buffer(wlan_private * priv) +int lbs_free_cmd_buffer(struct lbs_private *priv) { u32 ulbufsize; /* Someone needs to die for this. Slowly and painfully */ unsigned int i; struct cmd_ctrl_node *tempcmd_array; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_HOST); @@ -1541,13 +1620,13 @@ done: * @brief This function gets a free command node if available in * command free queue. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL */ -struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv) +struct cmd_ctrl_node *lbs_get_free_cmd_ctrl_node(struct lbs_private *priv) { struct cmd_ctrl_node *tempnode; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; unsigned long flags; lbs_deb_enter(LBS_DEB_HOST); @@ -1602,14 +1681,14 @@ static void cleanup_cmdnode(struct cmd_ctrl_node *ptempnode) /** * @brief This function initializes the command node. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param ptempnode A pointer to cmd_ctrl_node structure * @param cmd_oid cmd oid: treated as sub command * @param wait_option wait option: wait response or not * @param pdata_buf A pointer to informaion buffer * @return 0 or -1 */ -void libertas_set_cmd_ctrl_node(wlan_private * priv, +void lbs_set_cmd_ctrl_node(struct lbs_private *priv, struct cmd_ctrl_node *ptempnode, u32 cmd_oid, u16 wait_option, void *pdata_buf) { @@ -1630,19 +1709,19 @@ void libertas_set_cmd_ctrl_node(wlan_private * priv, * pending queue. It will put fimware back to PS mode * if applicable. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return 0 or -1 */ -int libertas_execute_next_command(wlan_private * priv) +int lbs_execute_next_command(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ctrl_node *cmdnode = NULL; struct cmd_ds_command *cmdptr; unsigned long flags; int ret = 0; // Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the - // only caller to us is libertas_thread() and we get even when a + // only caller to us is lbs_thread() and we get even when a // data packet is received lbs_deb_enter(LBS_DEB_THREAD); @@ -1683,7 +1762,7 @@ int libertas_execute_next_command(wlan_private * priv) /* * 1. Non-PS command: * Queue it. set needtowakeup to TRUE if current state - * is SLEEP, otherwise call libertas_ps_wakeup to send Exit_PS. + * is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS. * 2. PS command but not Exit_PS: * Ignore it. * 3. PS command Exit_PS: @@ -1702,7 +1781,7 @@ int libertas_execute_next_command(wlan_private * priv) since it is blocked in main_thread. */ adapter->needtowakeup = 1; } else - libertas_ps_wakeup(priv, 0); + lbs_ps_wakeup(priv, 0); ret = 0; goto done; @@ -1722,7 +1801,7 @@ int libertas_execute_next_command(wlan_private * priv) lbs_deb_host( "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); list_del((struct list_head *)cmdnode); - libertas_cleanup_and_insert_cmd(priv, cmdnode); + lbs_cleanup_and_insert_cmd(priv, cmdnode); ret = 0; goto done; @@ -1733,7 +1812,7 @@ int libertas_execute_next_command(wlan_private * priv) lbs_deb_host( "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); list_del((struct list_head *)cmdnode); - libertas_cleanup_and_insert_cmd(priv, cmdnode); + lbs_cleanup_and_insert_cmd(priv, cmdnode); adapter->needtowakeup = 1; ret = 0; @@ -1753,9 +1832,10 @@ int libertas_execute_next_command(wlan_private * priv) * check if in power save mode, if yes, put the device back * to PS mode */ - if ((adapter->psmode != WLAN802_11POWERMODECAM) && + if ((adapter->psmode != LBS802_11POWERMODECAM) && (adapter->psstate == PS_STATE_FULL_POWER) && - (adapter->connect_status == LIBERTAS_CONNECTED)) { + ((adapter->connect_status == LBS_CONNECTED) || + (adapter->mesh_connect_status == LBS_CONNECTED))) { if (adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) { /* check for valid WPA group keys */ @@ -1764,13 +1844,13 @@ int libertas_execute_next_command(wlan_private * priv) lbs_deb_host( "EXEC_NEXT_CMD: WPA enabled and GTK_SET" " go back to PS_SLEEP"); - libertas_ps_sleep(priv, 0); + lbs_ps_sleep(priv, 0); } } else { lbs_deb_host( "EXEC_NEXT_CMD: cmdpendingq empty, " "go back to PS_SLEEP"); - libertas_ps_sleep(priv, 0); + lbs_ps_sleep(priv, 0); } } } @@ -1781,7 +1861,7 @@ done: return ret; } -void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str) +void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str) { union iwreq_data iwrq; u8 buf[50]; @@ -1805,10 +1885,10 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str) lbs_deb_leave(LBS_DEB_WEXT); } -static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) +static int sendconfirmsleep(struct lbs_private *priv, u8 *cmdptr, u16 size) { unsigned long flags; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_HOST); @@ -1847,7 +1927,7 @@ static int sendconfirmsleep(wlan_private * priv, u8 * cmdptr, u16 size) return ret; } -void libertas_ps_sleep(wlan_private * priv, int wait_option) +void lbs_ps_sleep(struct lbs_private *priv, int wait_option) { lbs_deb_enter(LBS_DEB_HOST); @@ -1856,7 +1936,7 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option) * Remove this check if it is to be supported in IBSS mode also */ - libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL); lbs_deb_leave(LBS_DEB_HOST); @@ -1865,19 +1945,19 @@ void libertas_ps_sleep(wlan_private * priv, int wait_option) /** * @brief This function sends Exit_PS command to firmware. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param wait_option wait response or not * @return n/a */ -void libertas_ps_wakeup(wlan_private * priv, int wait_option) +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option) { __le32 Localpsmode; lbs_deb_enter(LBS_DEB_HOST); - Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM); + Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM); - libertas_prepare_and_send_command(priv, CMD_802_11_PS_MODE, + lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, CMD_SUBCMD_EXIT_PS, wait_option, 0, &Localpsmode); @@ -1888,14 +1968,14 @@ void libertas_ps_wakeup(wlan_private * priv, int wait_option) * @brief This function checks condition and prepares to * send sleep confirm command to firmware if ok. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param psmode Power Saving mode * @return n/a */ -void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode) +void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode) { unsigned long flags =0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u8 allowed = 1; lbs_deb_enter(LBS_DEB_HOST); @@ -1917,8 +1997,8 @@ void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode) spin_unlock_irqrestore(&adapter->driver_lock, flags); if (allowed) { - lbs_deb_host("sending libertas_ps_confirm_sleep\n"); - sendconfirmsleep(priv, (u8 *) & adapter->libertas_ps_confirm_sleep, + lbs_deb_host("sending lbs_ps_confirm_sleep\n"); + sendconfirmsleep(priv, (u8 *) & adapter->lbs_ps_confirm_sleep, sizeof(struct PS_CMD_ConfirmSleep)); } else { lbs_deb_host("sleep confirm has been delayed\n"); diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 8f90892..90f1c49 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c @@ -20,18 +20,18 @@ * reports disconnect to upper layer, clean tx/rx packets, * reset link state etc. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return n/a */ -void libertas_mac_event_disconnected(wlan_private * priv) +void lbs_mac_event_disconnected(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; union iwreq_data wrqu; - if (adapter->connect_status != LIBERTAS_CONNECTED) + if (adapter->connect_status != LBS_CONNECTED) return; - lbs_deb_enter(LBS_DEB_CMD); + lbs_deb_enter(LBS_DEB_ASSOC); memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -60,12 +60,7 @@ void libertas_mac_event_disconnected(wlan_private * priv) memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF)); adapter->nextSNRNF = 0; adapter->numSNRNF = 0; - lbs_deb_cmd("current SSID '%s', length %u\n", - escape_essid(adapter->curbssparams.ssid, - adapter->curbssparams.ssid_len), - adapter->curbssparams.ssid_len); - - adapter->connect_status = LIBERTAS_DISCONNECTED; + adapter->connect_status = LBS_DISCONNECTED; /* Clear out associated SSID and BSSID since connection is * no longer valid. @@ -77,7 +72,7 @@ void libertas_mac_event_disconnected(wlan_private * priv) if (adapter->psstate != PS_STATE_FULL_POWER) { /* make firmware to exit PS mode */ lbs_deb_cmd("disconnected, so exit PS mode\n"); - libertas_ps_wakeup(priv, 0); + lbs_ps_wakeup(priv, 0); } lbs_deb_leave(LBS_DEB_CMD); } @@ -85,11 +80,11 @@ void libertas_mac_event_disconnected(wlan_private * priv) /** * @brief This function handles MIC failure event. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @para event the event id * @return n/a */ -static void handle_mic_failureevent(wlan_private * priv, u32 event) +static void handle_mic_failureevent(struct lbs_private *priv, u32 event) { char buf[50]; @@ -104,15 +99,15 @@ static void handle_mic_failureevent(wlan_private * priv, u32 event) strcat(buf, "multicast "); } - libertas_send_iwevcustom_event(priv, buf); + lbs_send_iwevcustom_event(priv, buf); lbs_deb_leave(LBS_DEB_CMD); } -static int wlan_ret_reg_access(wlan_private * priv, +static int lbs_ret_reg_access(struct lbs_private *priv, u16 type, struct cmd_ds_command *resp) { int ret = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -152,12 +147,12 @@ static int wlan_ret_reg_access(wlan_private * priv, return ret; } -static int wlan_ret_get_hw_spec(wlan_private * priv, +static int lbs_ret_get_hw_spec(struct lbs_private *priv, struct cmd_ds_command *resp) { u32 i; struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; DECLARE_MAC_BUF(mac); @@ -183,7 +178,7 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { /* use the region code to search for the index */ - if (adapter->regioncode == libertas_region_code_to_index[i]) { + if (adapter->regioncode == lbs_region_code_to_index[i]) { break; } } @@ -201,12 +196,12 @@ static int wlan_ret_get_hw_spec(wlan_private * priv, if (priv->mesh_dev) memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); - if (libertas_set_regiontable(priv, adapter->regioncode, 0)) { + if (lbs_set_regiontable(priv, adapter->regioncode, 0)) { ret = -1; goto done; } - if (libertas_set_universaltable(priv, 0)) { + if (lbs_set_universaltable(priv, 0)) { ret = -1; goto done; } @@ -216,11 +211,11 @@ done: return ret; } -static int wlan_ret_802_11_sleep_params(wlan_private * priv, +static int lbs_ret_802_11_sleep_params(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -240,14 +235,14 @@ static int wlan_ret_802_11_sleep_params(wlan_private * priv, return 0; } -static int wlan_ret_802_11_stat(wlan_private * priv, +static int lbs_ret_802_11_stat(struct lbs_private *priv, struct cmd_ds_command *resp) { lbs_deb_enter(LBS_DEB_CMD); /* currently adapter->wlan802_11Stat is unused struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; // TODO Convert it to Big endian befor copy memcpy(&adapter->wlan802_11Stat, @@ -257,7 +252,7 @@ static int wlan_ret_802_11_stat(wlan_private * priv, return 0; } -static int wlan_ret_802_11_snmp_mib(wlan_private * priv, +static int lbs_ret_802_11_snmp_mib(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; @@ -299,12 +294,12 @@ static int wlan_ret_802_11_snmp_mib(wlan_private * priv, return 0; } -static int wlan_ret_802_11_key_material(wlan_private * priv, +static int lbs_ret_802_11_key_material(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_key_material *pkeymaterial = &resp->params.keymaterial; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u16 action = le16_to_cpu(pkeymaterial->action); lbs_deb_enter(LBS_DEB_CMD); @@ -355,11 +350,11 @@ static int wlan_ret_802_11_key_material(wlan_private * priv, return 0; } -static int wlan_ret_802_11_mac_address(wlan_private * priv, +static int lbs_ret_802_11_mac_address(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -369,11 +364,11 @@ static int wlan_ret_802_11_mac_address(wlan_private * priv, return 0; } -static int wlan_ret_802_11_rf_tx_power(wlan_private * priv, +static int lbs_ret_802_11_rf_tx_power(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -385,11 +380,11 @@ static int wlan_ret_802_11_rf_tx_power(wlan_private * priv, return 0; } -static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv, +static int lbs_ret_802_11_rate_adapt_rateset(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -402,11 +397,11 @@ static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv, return 0; } -static int wlan_ret_802_11_data_rate(wlan_private * priv, +static int lbs_ret_802_11_data_rate(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -416,18 +411,18 @@ static int wlan_ret_802_11_data_rate(wlan_private * priv, /* FIXME: get actual rates FW can do if this command actually returns * all data rates supported. */ - adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]); + adapter->cur_rate = lbs_fw_index_to_data_rate(pdatarate->rates[0]); lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", adapter->cur_rate); lbs_deb_leave(LBS_DEB_CMD); return 0; } -static int wlan_ret_802_11_rf_channel(wlan_private * priv, +static int lbs_ret_802_11_rf_channel(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u16 action = le16_to_cpu(rfchannel->action); u16 newchannel = le16_to_cpu(rfchannel->currentchannel); @@ -446,11 +441,11 @@ static int wlan_ret_802_11_rf_channel(wlan_private * priv, return 0; } -static int wlan_ret_802_11_rssi(wlan_private * priv, +static int lbs_ret_802_11_rssi(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -477,12 +472,12 @@ static int wlan_ret_802_11_rssi(wlan_private * priv, return 0; } -static int wlan_ret_802_11_eeprom_access(wlan_private * priv, +static int lbs_ret_802_11_eeprom_access(struct lbs_private *priv, struct cmd_ds_command *resp) { - wlan_adapter *adapter = priv->adapter; - struct wlan_ioctl_regrdwr *pbuf; - pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_ioctl_regrdwr *pbuf; + pbuf = (struct lbs_ioctl_regrdwr *) adapter->prdeeprom; lbs_deb_enter_args(LBS_DEB_CMD, "len %d", le16_to_cpu(resp->params.rdeeprom.bytecount)); @@ -503,11 +498,11 @@ static int wlan_ret_802_11_eeprom_access(wlan_private * priv, return 0; } -static int wlan_ret_get_log(wlan_private * priv, +static int lbs_ret_get_log(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_CMD); @@ -518,11 +513,11 @@ static int wlan_ret_get_log(wlan_private * priv, return 0; } -static int libertas_ret_802_11_enable_rsn(wlan_private * priv, +static int lbs_ret_802_11_enable_rsn(struct lbs_private *priv, struct cmd_ds_command *resp) { struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u32 * pdata_buf = adapter->cur_cmd->pdata_buf; lbs_deb_enter(LBS_DEB_CMD); @@ -536,13 +531,51 @@ static int libertas_ret_802_11_enable_rsn(wlan_private * priv, return 0; } +static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv, + struct cmd_ds_command *resp) +{ + struct cmd_ds_802_11_beacon_control *bcn_ctrl = + &resp->params.bcn_ctrl; + struct lbs_adapter *adapter = priv->adapter; + + lbs_deb_enter(LBS_DEB_CMD); + + if (bcn_ctrl->action == CMD_ACT_GET) { + adapter->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); + adapter->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); + } + + lbs_deb_enter(LBS_DEB_CMD); + return 0; +} + +static int lbs_ret_802_11_subscribe_event(struct lbs_private *priv, + struct cmd_ds_command *resp) +{ + struct lbs_adapter *adapter = priv->adapter; + struct cmd_ds_802_11_subscribe_event *cmd_event = + &resp->params.subscribe_event; + struct cmd_ds_802_11_subscribe_event *dst_event = + adapter->cur_cmd->pdata_buf; + + lbs_deb_enter(LBS_DEB_CMD); + + if (dst_event->action == cpu_to_le16(CMD_ACT_GET)) { + dst_event->events = le16_to_cpu(cmd_event->events); + memcpy(dst_event->tlv, cmd_event->tlv, sizeof(dst_event->tlv)); + } + + lbs_deb_leave(LBS_DEB_CMD); + return 0; +} + static inline int handle_cmd_response(u16 respcmd, struct cmd_ds_command *resp, - wlan_private *priv) + struct lbs_private *priv) { int ret = 0; unsigned long flags; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_HOST); @@ -550,47 +583,47 @@ static inline int handle_cmd_response(u16 respcmd, case CMD_RET(CMD_MAC_REG_ACCESS): case CMD_RET(CMD_BBP_REG_ACCESS): case CMD_RET(CMD_RF_REG_ACCESS): - ret = wlan_ret_reg_access(priv, respcmd, resp); + ret = lbs_ret_reg_access(priv, respcmd, resp); break; case CMD_RET(CMD_GET_HW_SPEC): - ret = wlan_ret_get_hw_spec(priv, resp); + ret = lbs_ret_get_hw_spec(priv, resp); break; case CMD_RET(CMD_802_11_SCAN): - ret = libertas_ret_80211_scan(priv, resp); + ret = lbs_ret_80211_scan(priv, resp); break; case CMD_RET(CMD_802_11_GET_LOG): - ret = wlan_ret_get_log(priv, resp); + ret = lbs_ret_get_log(priv, resp); break; case CMD_RET_802_11_ASSOCIATE: case CMD_RET(CMD_802_11_ASSOCIATE): case CMD_RET(CMD_802_11_REASSOCIATE): - ret = libertas_ret_80211_associate(priv, resp); + ret = lbs_ret_80211_associate(priv, resp); break; case CMD_RET(CMD_802_11_DISASSOCIATE): case CMD_RET(CMD_802_11_DEAUTHENTICATE): - ret = libertas_ret_80211_disassociate(priv, resp); + ret = lbs_ret_80211_disassociate(priv, resp); break; case CMD_RET(CMD_802_11_AD_HOC_START): case CMD_RET(CMD_802_11_AD_HOC_JOIN): - ret = libertas_ret_80211_ad_hoc_start(priv, resp); + ret = lbs_ret_80211_ad_hoc_start(priv, resp); break; case CMD_RET(CMD_802_11_GET_STAT): - ret = wlan_ret_802_11_stat(priv, resp); + ret = lbs_ret_802_11_stat(priv, resp); break; case CMD_RET(CMD_802_11_SNMP_MIB): - ret = wlan_ret_802_11_snmp_mib(priv, resp); + ret = lbs_ret_802_11_snmp_mib(priv, resp); break; case CMD_RET(CMD_802_11_RF_TX_POWER): - ret = wlan_ret_802_11_rf_tx_power(priv, resp); + ret = lbs_ret_802_11_rf_tx_power(priv, resp); break; case CMD_RET(CMD_802_11_SET_AFC): @@ -612,45 +645,45 @@ static inline int handle_cmd_response(u16 respcmd, break; case CMD_RET(CMD_802_11_ENABLE_RSN): - ret = libertas_ret_802_11_enable_rsn(priv, resp); + ret = lbs_ret_802_11_enable_rsn(priv, resp); break; case CMD_RET(CMD_802_11_DATA_RATE): - ret = wlan_ret_802_11_data_rate(priv, resp); + ret = lbs_ret_802_11_data_rate(priv, resp); break; case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET): - ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp); + ret = lbs_ret_802_11_rate_adapt_rateset(priv, resp); break; case CMD_RET(CMD_802_11_RF_CHANNEL): - ret = wlan_ret_802_11_rf_channel(priv, resp); + ret = lbs_ret_802_11_rf_channel(priv, resp); break; case CMD_RET(CMD_802_11_RSSI): - ret = wlan_ret_802_11_rssi(priv, resp); + ret = lbs_ret_802_11_rssi(priv, resp); break; case CMD_RET(CMD_802_11_MAC_ADDRESS): - ret = wlan_ret_802_11_mac_address(priv, resp); + ret = lbs_ret_802_11_mac_address(priv, resp); break; case CMD_RET(CMD_802_11_AD_HOC_STOP): - ret = libertas_ret_80211_ad_hoc_stop(priv, resp); + ret = lbs_ret_80211_ad_hoc_stop(priv, resp); break; case CMD_RET(CMD_802_11_KEY_MATERIAL): - ret = wlan_ret_802_11_key_material(priv, resp); + ret = lbs_ret_802_11_key_material(priv, resp); break; case CMD_RET(CMD_802_11_EEPROM_ACCESS): - ret = wlan_ret_802_11_eeprom_access(priv, resp); + ret = lbs_ret_802_11_eeprom_access(priv, resp); break; case CMD_RET(CMD_802_11D_DOMAIN_INFO): - ret = libertas_ret_802_11d_domain_info(priv, resp); + ret = lbs_ret_802_11d_domain_info(priv, resp); break; case CMD_RET(CMD_802_11_SLEEP_PARAMS): - ret = wlan_ret_802_11_sleep_params(priv, resp); + ret = lbs_ret_802_11_sleep_params(priv, resp); break; case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT): spin_lock_irqsave(&adapter->driver_lock, flags); @@ -671,6 +704,10 @@ static inline int handle_cmd_response(u16 respcmd, sizeof(struct cmd_ds_802_11_led_ctrl)); spin_unlock_irqrestore(&adapter->driver_lock, flags); break; + case CMD_RET(CMD_802_11_SUBSCRIBE_EVENT): + ret = lbs_ret_802_11_subscribe_event(priv, resp); + break; + case CMD_RET(CMD_802_11_PWR_CFG): spin_lock_irqsave(&adapter->driver_lock, flags); memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg, @@ -704,6 +741,10 @@ static inline int handle_cmd_response(u16 respcmd, memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh, sizeof(resp->params.mesh)); break; + case CMD_RET(CMD_802_11_BEACON_CTRL): + ret = lbs_ret_802_11_bcn_ctrl(priv, resp); + break; + default: lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n", resp->command); @@ -713,11 +754,11 @@ static inline int handle_cmd_response(u16 respcmd, return ret; } -int libertas_process_rx_command(wlan_private * priv) +int lbs_process_rx_command(struct lbs_private *priv) { u16 respcmd; struct cmd_ds_command *resp; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; ulong flags; u16 result; @@ -749,7 +790,7 @@ int libertas_process_rx_command(wlan_private * priv) if (!(respcmd & 0x8000)) { lbs_deb_host("invalid response!\n"); adapter->cur_cmd_retcode = -1; - __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -774,27 +815,27 @@ int libertas_process_rx_command(wlan_private * priv) /* * We should not re-try enter-ps command in * ad-hoc mode. It takes place in - * libertas_execute_next_command(). + * lbs_execute_next_command(). */ if (adapter->mode == IW_MODE_ADHOC && action == CMD_SUBCMD_ENTER_PS) - adapter->psmode = WLAN802_11POWERMODECAM; + adapter->psmode = LBS802_11POWERMODECAM; } else if (action == CMD_SUBCMD_ENTER_PS) { adapter->needtowakeup = 0; adapter->psstate = PS_STATE_AWAKE; lbs_deb_host("CMD_RESP: ENTER_PS command response\n"); - if (adapter->connect_status != LIBERTAS_CONNECTED) { + if (adapter->connect_status != LBS_CONNECTED) { /* * When Deauth Event received before Enter_PS command * response, We need to wake up the firmware. */ lbs_deb_host( - "disconnected, invoking libertas_ps_wakeup\n"); + "disconnected, invoking lbs_ps_wakeup\n"); spin_unlock_irqrestore(&adapter->driver_lock, flags); mutex_unlock(&adapter->lock); - libertas_ps_wakeup(priv, 0); + lbs_ps_wakeup(priv, 0); mutex_lock(&adapter->lock); spin_lock_irqsave(&adapter->driver_lock, flags); } @@ -806,7 +847,7 @@ int libertas_process_rx_command(wlan_private * priv) lbs_deb_host("CMD_RESP: PS action 0x%X\n", action); } - __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -837,7 +878,7 @@ int libertas_process_rx_command(wlan_private * priv) } - __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; adapter->cur_cmd = NULL; spin_unlock_irqrestore(&adapter->driver_lock, flags); @@ -853,7 +894,7 @@ int libertas_process_rx_command(wlan_private * priv) spin_lock_irqsave(&adapter->driver_lock, flags); if (adapter->cur_cmd) { /* Clean up and Put current command back to cmdfreeq */ - __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); + __lbs_cleanup_and_insert_cmd(priv, adapter->cur_cmd); adapter->nr_cmd_pending--; WARN_ON(adapter->nr_cmd_pending > 128); adapter->cur_cmd = NULL; @@ -866,38 +907,38 @@ done: return ret; } -int libertas_process_event(wlan_private * priv) +int lbs_process_event(struct lbs_private *priv) { int ret = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; u32 eventcause; lbs_deb_enter(LBS_DEB_CMD); spin_lock_irq(&adapter->driver_lock); - eventcause = adapter->eventcause; + eventcause = adapter->eventcause >> SBI_EVENT_CAUSE_SHIFT; spin_unlock_irq(&adapter->driver_lock); - lbs_deb_cmd("event cause 0x%x\n", eventcause); + lbs_deb_cmd("event cause %d\n", eventcause); - switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) { + switch (eventcause) { case MACREG_INT_CODE_LINK_SENSED: lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n"); break; case MACREG_INT_CODE_DEAUTHENTICATED: lbs_deb_cmd("EVENT: deauthenticated\n"); - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); break; case MACREG_INT_CODE_DISASSOCIATED: lbs_deb_cmd("EVENT: disassociated\n"); - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); break; - case MACREG_INT_CODE_LINK_LOSE_NO_SCAN: + case MACREG_INT_CODE_LINK_LOST_NO_SCAN: lbs_deb_cmd("EVENT: link lost\n"); - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); break; case MACREG_INT_CODE_PS_SLEEP: @@ -911,7 +952,7 @@ int libertas_process_event(wlan_private * priv) } adapter->psstate = PS_STATE_PRE_SLEEP; - libertas_ps_confirm_sleep(priv, (u16) adapter->psmode); + lbs_ps_confirm_sleep(priv, (u16) adapter->psmode); break; @@ -932,10 +973,10 @@ int libertas_process_event(wlan_private * priv) * wait for the command processing to finish * before resuming sending * adapter->needtowakeup will be set to FALSE - * in libertas_ps_wakeup() + * in lbs_ps_wakeup() */ lbs_deb_cmd("waking up ...\n"); - libertas_ps_wakeup(priv, 0); + lbs_ps_wakeup(priv, 0); } break; @@ -979,7 +1020,7 @@ int libertas_process_event(wlan_private * priv) break; } lbs_pr_info("EVENT: MESH_AUTO_STARTED\n"); - adapter->connect_status = LIBERTAS_CONNECTED; + adapter->mesh_connect_status = LBS_CONNECTED; if (priv->mesh_open == 1) { netif_wake_queue(priv->mesh_dev); netif_carrier_on(priv->mesh_dev); @@ -989,8 +1030,7 @@ int libertas_process_event(wlan_private * priv) break; default: - lbs_pr_alert("EVENT: unknown event id 0x%04x\n", - eventcause >> SBI_EVENT_CAUSE_SHIFT); + lbs_pr_alert("EVENT: unknown event id %d\n", eventcause); break; } diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index 0bda0b5..1d881ae 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -11,14 +11,14 @@ #include "host.h" #include "debugfs.h" -static struct dentry *libertas_dir = NULL; +static struct dentry *lbs_dir; static char *szStates[] = { "Connected", "Disconnected" }; #ifdef PROC_DEBUG -static void libertas_debug_init(wlan_private * priv, struct net_device *dev); +static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev); #endif static int open_file_generic(struct inode *inode, struct file *file) @@ -35,10 +35,10 @@ static ssize_t write_file_dummy(struct file *file, const char __user *buf, static const size_t len = PAGE_SIZE; -static ssize_t libertas_dev_info(struct file *file, char __user *userbuf, +static ssize_t lbs_dev_info(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; size_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -56,10 +56,10 @@ static ssize_t libertas_dev_info(struct file *file, char __user *userbuf, } -static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, +static ssize_t lbs_getscantable(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; size_t pos = 0; int numscansdone = 0, res; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -98,11 +98,11 @@ static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, return res; } -static ssize_t libertas_sleepparams_write(struct file *file, +static ssize_t lbs_sleepparams_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t buf_size, res; int p1, p2, p3, p4, p5, p6; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -125,7 +125,7 @@ static ssize_t libertas_sleepparams_write(struct file *file, priv->adapter->sp.sp_extsleepclk = p5; priv->adapter->sp.sp_reserved = p6; - res = libertas_prepare_and_send_command(priv, + res = lbs_prepare_and_send_command(priv, CMD_802_11_SLEEP_PARAMS, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -140,17 +140,17 @@ out_unlock: return res; } -static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf, +static ssize_t lbs_sleepparams_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = file->private_data; + struct lbs_adapter *adapter = priv->adapter; ssize_t res; size_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; - res = libertas_prepare_and_send_command(priv, + res = lbs_prepare_and_send_command(priv, CMD_802_11_SLEEP_PARAMS, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -171,10 +171,10 @@ out_unlock: return res; } -static ssize_t libertas_extscan(struct file *file, const char __user *userbuf, +static ssize_t lbs_extscan(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; union iwreq_data wrqu; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -186,7 +186,7 @@ static ssize_t libertas_extscan(struct file *file, const char __user *userbuf, goto out_unlock; } - libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); + lbs_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); memset(&wrqu, 0, sizeof(union iwreq_data)); wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); @@ -196,45 +196,8 @@ out_unlock: return count; } -static int libertas_parse_chan(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur) -{ - char *start, *end, *hold, *str; - int i = 0; - - start = strstr(buf, "chan="); - if (!start) - return -EINVAL; - start += 5; - end = strchr(start, ' '); - if (!end) - end = buf + count; - hold = kzalloc((end - start)+1, GFP_KERNEL); - if (!hold) - return -ENOMEM; - strncpy(hold, start, end - start); - hold[(end-start)+1] = '\0'; - while(hold && (str = strsep(&hold, ","))) { - int chan; - char band, passive = 0; - sscanf(str, "%d%c%c", &chan, &band, &passive); - scan_cfg->chanlist[i].channumber = chan; - scan_cfg->chanlist[i].scantype = passive ? 1 : 0; - if (band == 'b' || band == 'g') - scan_cfg->chanlist[i].radiotype = 0; - else if (band == 'a') - scan_cfg->chanlist[i].radiotype = 1; - - scan_cfg->chanlist[i].scantime = dur; - i++; - } - - kfree(hold); - return i; -} - -static void libertas_parse_bssid(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) +static void lbs_parse_bssid(char *buf, size_t count, + struct lbs_ioctl_user_scan_cfg *scan_cfg) { char *hold; unsigned int mac[ETH_ALEN]; @@ -247,8 +210,8 @@ static void libertas_parse_bssid(char *buf, size_t count, memcpy(scan_cfg->bssid, mac, ETH_ALEN); } -static void libertas_parse_ssid(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) +static void lbs_parse_ssid(char *buf, size_t count, + struct lbs_ioctl_user_scan_cfg *scan_cfg) { char *hold, *end; ssize_t size; @@ -267,7 +230,7 @@ static void libertas_parse_ssid(char *buf, size_t count, return; } -static int libertas_parse_clear(char *buf, size_t count, const char *tag) +static int lbs_parse_clear(char *buf, size_t count, const char *tag) { char *hold; int val; @@ -284,8 +247,8 @@ static int libertas_parse_clear(char *buf, size_t count, const char *tag) return val; } -static int libertas_parse_dur(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) +static int lbs_parse_dur(char *buf, size_t count, + struct lbs_ioctl_user_scan_cfg *scan_cfg) { char *hold; int val; @@ -299,25 +262,8 @@ static int libertas_parse_dur(char *buf, size_t count, return val; } -static void libertas_parse_probes(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) -{ - char *hold; - int val; - - hold = strstr(buf, "probes="); - if (!hold) - return; - hold += 7; - sscanf(hold, "%d", &val); - - scan_cfg->numprobes = val; - - return; -} - -static void libertas_parse_type(char *buf, size_t count, - struct wlan_ioctl_user_scan_cfg *scan_cfg) +static void lbs_parse_type(char *buf, size_t count, + struct lbs_ioctl_user_scan_cfg *scan_cfg) { char *hold; int val; @@ -337,19 +283,19 @@ static void libertas_parse_type(char *buf, size_t count, return; } -static ssize_t libertas_setuserscan(struct file *file, +static ssize_t lbs_setuserscan(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; - struct wlan_ioctl_user_scan_cfg *scan_cfg; + struct lbs_ioctl_user_scan_cfg *scan_cfg; union iwreq_data wrqu; int dur; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; - scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL); + scan_cfg = kzalloc(sizeof(struct lbs_ioctl_user_scan_cfg), GFP_KERNEL); if (!scan_cfg) return -ENOMEM; @@ -359,18 +305,16 @@ static ssize_t libertas_setuserscan(struct file *file, goto out_unlock; } - scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY; + scan_cfg->bsstype = LBS_SCAN_BSS_TYPE_ANY; - dur = libertas_parse_dur(buf, count, scan_cfg); - libertas_parse_chan(buf, count, scan_cfg, dur); - libertas_parse_bssid(buf, count, scan_cfg); - scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid="); - libertas_parse_ssid(buf, count, scan_cfg); - scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid="); - libertas_parse_probes(buf, count, scan_cfg); - libertas_parse_type(buf, count, scan_cfg); + dur = lbs_parse_dur(buf, count, scan_cfg); + lbs_parse_bssid(buf, count, scan_cfg); + scan_cfg->clear_bssid = lbs_parse_clear(buf, count, "clear_bssid="); + lbs_parse_ssid(buf, count, scan_cfg); + scan_cfg->clear_ssid = lbs_parse_clear(buf, count, "clear_ssid="); + lbs_parse_type(buf, count, scan_cfg); - wlan_scan_networks(priv, scan_cfg, 1); + lbs_scan_networks(priv, scan_cfg, 1); wait_event_interruptible(priv->adapter->cmd_pending, !priv->adapter->nr_cmd_pending); @@ -383,524 +327,162 @@ out_unlock: return count; } -static int libertas_event_initcmd(wlan_private *priv, void **response_buf, - struct cmd_ctrl_node **cmdnode, - struct cmd_ds_command **cmd) -{ - u16 wait_option = CMD_OPTION_WAITFORRSP; - - if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) { - lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n"); - return -ENOMEM; - } - if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) { - lbs_deb_debugfs("failed to allocate response buffer!\n"); - return -ENOMEM; - } - libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL); - init_waitqueue_head(&(*cmdnode)->cmdwait_q); - (*cmdnode)->pdata_buf = *response_buf; - (*cmdnode)->cmdflags |= CMD_F_HOSTCMD; - (*cmdnode)->cmdwaitqwoken = 0; - *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr; - (*cmd)->command = cpu_to_le16(CMD_802_11_SUBSCRIBE_EVENT); - (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum); - (*cmd)->result = 0; - return 0; -} -static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) +/* + * When calling CMD_802_11_SUBSCRIBE_EVENT with CMD_ACT_GET, me might + * get a bunch of vendor-specific TLVs (a.k.a. IEs) back from the + * firmware. Here's an example: + * 04 01 02 00 00 00 05 01 02 00 00 00 06 01 02 00 + * 00 00 07 01 02 00 3c 00 00 00 00 00 00 00 03 03 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * + * The 04 01 is the TLV type (here TLV_TYPE_RSSI_LOW), 02 00 is the length, + * 00 00 are the data bytes of this TLV. For this TLV, their meaning is + * defined in mrvlietypes_thresholds + * + * This function searches in this TLV data chunk for a given TLV type + * and returns a pointer to the first data byte of the TLV, or to NULL + * if the TLV hasn't been found. + */ +static void *lbs_tlv_find(u16 tlv_type, const u8 *tlv, u16 size) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; + __le16 le_type = cpu_to_le16(tlv_type); ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); - return res; - } - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_rssithreshold *Lowrssi; - case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW): - Lowrssi = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - Lowrssi->rssivalue, - Lowrssi->rssifreq, - (event->events & cpu_to_le16(0x0001))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_snrthreshold); - break; - } - } - - kfree(response_buf); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - free_page(addr); - return res; + struct mrvlietypesheader *tlv_h; + while (pos < size) { + u16 length; + tlv_h = (struct mrvlietypesheader *) tlv; + if (tlv_h->type == le_type) + return tlv_h; + if (tlv_h->len == 0) + return NULL; + length = le16_to_cpu(tlv_h->len) + + sizeof(struct mrvlietypesheader); + pos += length; + tlv += length; + } + return NULL; } -static u16 libertas_get_events_bitmap(wlan_private *priv) -{ - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res; - u16 event_bitmap; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - return res; - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - return 0; - } - - if (le16_to_cpu(pcmdptr->command) != CMD_RET(CMD_802_11_SUBSCRIBE_EVENT)) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - return 0; - } - - event = (struct cmd_ds_802_11_subscribe_event *)(response_buf + S_DS_GEN); - event_bitmap = le16_to_cpu(event->events); - kfree(response_buf); - return event_bitmap; -} -static ssize_t libertas_lowrssi_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) +/* + * This just gets the bitmap of currently subscribed events. Used when + * adding an additonal event subscription. + */ +static u16 lbs_get_events_bitmap(struct lbs_private *priv) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_rssithreshold *rssi_threshold; - void *response_buf; - u16 event_bitmap; - u8 *ptr; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); - if (res != 3) { - res = -EFAULT; - goto out_unlock; - } - - event_bitmap = libertas_get_events_bitmap(priv); + ssize_t res; - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; + struct cmd_ds_802_11_subscribe_event *events = kzalloc( + sizeof(struct cmd_ds_802_11_subscribe_event), + GFP_KERNEL); - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_rssithreshold)); - - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr); - rssi_threshold->header.type = cpu_to_le16(0x0104); - rssi_threshold->header.len = cpu_to_le16(2); - rssi_threshold->rssivalue = value; - rssi_threshold->rssifreq = freq; - event_bitmap |= subscribed ? 0x0001 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } + res = lbs_prepare_and_send_command(priv, + CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET, + CMD_OPTION_WAITFORRSP, 0, events); - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); + if (res) { + kfree(events); return 0; } - - res = count; -out_unlock: - free_page(addr); - return res; + return le16_to_cpu(events->events); } -static ssize_t libertas_lowsnr_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; - ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); - return res; - } - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_snrthreshold *LowSnr; - case __constant_cpu_to_le16(TLV_TYPE_SNR_LOW): - LowSnr = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - LowSnr->snrvalue, - LowSnr->snrfreq, - (event->events & cpu_to_le16(0x0002))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_snrthreshold); - break; - } - } - - kfree(response_buf); - - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - free_page(addr); - return res; -} -static ssize_t libertas_lowsnr_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) +static ssize_t lbs_threshold_read( + u16 tlv_type, u16 event_mask, + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_snrthreshold *snr_threshold; - void *response_buf; - u16 event_bitmap; - u8 *ptr; + struct lbs_private *priv = file->private_data; + ssize_t res = 0; + size_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + u8 value; + u8 freq; - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); - if (res != 3) { - res = -EFAULT; - goto out_unlock; - } - - event_bitmap = libertas_get_events_bitmap(priv); - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; + struct cmd_ds_802_11_subscribe_event *events = kzalloc( + sizeof(struct cmd_ds_802_11_subscribe_event), + GFP_KERNEL); + struct mrvlietypes_thresholds *got; - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_snrthreshold)); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr); - snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_LOW); - snr_threshold->header.len = cpu_to_le16(2); - snr_threshold->snrvalue = value; - snr_threshold->snrfreq = freq; - event_bitmap |= subscribed ? 0x0002 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - - res = count; - -out_unlock: - free_page(addr); - return res; -} - -static ssize_t libertas_failcount_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; - ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); + res = lbs_prepare_and_send_command(priv, + CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_GET, + CMD_OPTION_WAITFORRSP, 0, events); + if (res) { + kfree(events); return res; } - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; + got = lbs_tlv_find(tlv_type, events->tlv, sizeof(events->tlv)); + if (got) { + value = got->value; + freq = got->freq; } + kfree(events); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_failurecount *failcount; - case __constant_cpu_to_le16(TLV_TYPE_FAILCOUNT): - failcount = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - failcount->failvalue, - failcount->Failfreq, - (event->events & cpu_to_le16(0x0004))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_failurecount); - break; - } - } + if (got) + pos += snprintf(buf, len, "%d %d %d\n", value, freq, + !!(le16_to_cpu(events->events) & event_mask)); - kfree(response_buf); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); + free_page(addr); return res; } -static ssize_t libertas_failcount_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) + +static ssize_t lbs_threshold_write( + u16 tlv_type, u16 event_mask, + struct file *file, + const char __user *userbuf, + size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_failurecount *failcount; - void *response_buf; - u16 event_bitmap; - u8 *ptr; + int value, freq, curr_mask, new_mask; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; + struct cmd_ds_802_11_subscribe_event *events; buf_size = min(count, len - 1); if (copy_from_user(buf, userbuf, buf_size)) { res = -EFAULT; goto out_unlock; } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); + res = sscanf(buf, "%d %d %d", &value, &freq, &new_mask); if (res != 3) { res = -EFAULT; goto out_unlock; } + curr_mask = lbs_get_events_bitmap(priv); - event_bitmap = libertas_get_events_bitmap(priv); - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_failurecount)); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - failcount = (struct mrvlietypes_failurecount *)(ptr); - failcount->header.type = cpu_to_le16(TLV_TYPE_FAILCOUNT); - failcount->header.len = cpu_to_le16(2); - failcount->failvalue = value; - failcount->Failfreq = freq; - event_bitmap |= subscribed ? 0x0004 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = (struct cmd_ds_command *)response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; + if (new_mask) + new_mask = curr_mask | event_mask; + else + new_mask = curr_mask & ~event_mask; + + /* Now everything is set and we can send stuff down to the firmware */ + events = kzalloc( + sizeof(struct cmd_ds_802_11_subscribe_event), + GFP_KERNEL); + if (events) { + struct mrvlietypes_thresholds *tlv = + (struct mrvlietypes_thresholds *) events->tlv; + events->action = cpu_to_le16(CMD_ACT_SET); + events->events = cpu_to_le16(new_mask); + tlv->header.type = cpu_to_le16(tlv_type); + tlv->header.len = cpu_to_le16( + sizeof(struct mrvlietypes_thresholds) - + sizeof(struct mrvlietypesheader)); + tlv->value = value; + if (tlv_type != TLV_TYPE_BCNMISS) + tlv->freq = freq; + lbs_prepare_and_send_command(priv, + CMD_802_11_SUBSCRIBE_EVENT, CMD_ACT_SET, + CMD_OPTION_WAITFORRSP, 0, events); + kfree(events); } res = count; @@ -909,464 +491,126 @@ out_unlock: return res; } -static ssize_t libertas_bcnmiss_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; - ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); - return res; - } - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - free_page(addr); - kfree(response_buf); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - free_page(addr); - kfree(response_buf); - return 0; - } - - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_beaconsmissed *bcnmiss; - case __constant_cpu_to_le16(TLV_TYPE_BCNMISS): - bcnmiss = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d N/A %d\n", - bcnmiss->beaconmissed, - (event->events & cpu_to_le16(0x0008))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_beaconsmissed); - break; - } - } - - kfree(response_buf); - - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - free_page(addr); - return res; -} -static ssize_t libertas_bcnmiss_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) +static ssize_t lbs_lowrssi_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_beaconsmissed *bcnmiss; - void *response_buf; - u16 event_bitmap; - u8 *ptr; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); - if (res != 3) { - res = -EFAULT; - goto out_unlock; - } - - event_bitmap = libertas_get_events_bitmap(priv); - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_beaconsmissed)); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - bcnmiss = (struct mrvlietypes_beaconsmissed *)(ptr); - bcnmiss->header.type = cpu_to_le16(TLV_TYPE_BCNMISS); - bcnmiss->header.len = cpu_to_le16(2); - bcnmiss->beaconmissed = value; - event_bitmap |= subscribed ? 0x0008 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - free_page(addr); - kfree(response_buf); - return 0; - } - - res = count; -out_unlock: - free_page(addr); - return res; + return lbs_threshold_read(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW, + file, userbuf, count, ppos); } -static ssize_t libertas_highrssi_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) -{ - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; - ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); - return res; - } +static ssize_t lbs_lowrssi_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_RSSI_LOW, CMD_SUBSCRIBE_RSSI_LOW, + file, userbuf, count, ppos); +} - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); +static ssize_t lbs_lowsnr_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_read(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW, + file, userbuf, count, ppos); +} - pcmdptr = response_buf; - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } +static ssize_t lbs_lowsnr_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_SNR_LOW, CMD_SUBSCRIBE_SNR_LOW, + file, userbuf, count, ppos); +} - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_rssithreshold *Highrssi; - case __constant_cpu_to_le16(TLV_TYPE_RSSI_HIGH): - Highrssi = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - Highrssi->rssivalue, - Highrssi->rssifreq, - (event->events & cpu_to_le16(0x0010))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_snrthreshold); - break; - } - } +static ssize_t lbs_failcount_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_read(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT, + file, userbuf, count, ppos); +} - kfree(response_buf); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - free_page(addr); - return res; +static ssize_t lbs_failcount_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_FAILCOUNT, CMD_SUBSCRIBE_FAILCOUNT, + file, userbuf, count, ppos); } -static ssize_t libertas_highrssi_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) + +static ssize_t lbs_highrssi_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_rssithreshold *rssi_threshold; - void *response_buf; - u16 event_bitmap; - u8 *ptr; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; + return lbs_threshold_read(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH, + file, userbuf, count, ppos); +} - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); - if (res != 3) { - res = -EFAULT; - goto out_unlock; - } - event_bitmap = libertas_get_events_bitmap(priv); +static ssize_t lbs_highrssi_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_RSSI_HIGH, CMD_SUBSCRIBE_RSSI_HIGH, + file, userbuf, count, ppos); +} - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_rssithreshold)); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - rssi_threshold = (struct mrvlietypes_rssithreshold *)(ptr); - rssi_threshold->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH); - rssi_threshold->header.len = cpu_to_le16(2); - rssi_threshold->rssivalue = value; - rssi_threshold->rssifreq = freq; - event_bitmap |= subscribed ? 0x0010 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - return 0; - } +static ssize_t lbs_highsnr_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_read(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH, + file, userbuf, count, ppos); +} - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - return 0; - } - res = count; -out_unlock: - free_page(addr); - return res; +static ssize_t lbs_highsnr_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_SNR_HIGH, CMD_SUBSCRIBE_SNR_HIGH, + file, userbuf, count, ppos); } -static ssize_t libertas_highsnr_read(struct file *file, char __user *userbuf, - size_t count, loff_t *ppos) +static ssize_t lbs_bcnmiss_read( + struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - void *response_buf; - int res, cmd_len; - ssize_t pos = 0; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) { - free_page(addr); - return res; - } - - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_GET); - pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - event = (void *)(response_buf + S_DS_GEN); - while (cmd_len < le16_to_cpu(pcmdptr->size)) { - struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); - switch (header->type) { - struct mrvlietypes_snrthreshold *HighSnr; - case __constant_cpu_to_le16(TLV_TYPE_SNR_HIGH): - HighSnr = (void *)(response_buf + cmd_len); - pos += snprintf(buf+pos, len-pos, "%d %d %d\n", - HighSnr->snrvalue, - HighSnr->snrfreq, - (event->events & cpu_to_le16(0x0020))?1:0); - default: - cmd_len += sizeof(struct mrvlietypes_snrthreshold); - break; - } - } + return lbs_threshold_read(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS, + file, userbuf, count, ppos); +} - kfree(response_buf); - res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); - free_page(addr); - return res; +static ssize_t lbs_bcnmiss_write( + struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + return lbs_threshold_write(TLV_TYPE_BCNMISS, CMD_SUBSCRIBE_BCNMISS, + file, userbuf, count, ppos); } -static ssize_t libertas_highsnr_write(struct file *file, - const char __user *userbuf, - size_t count, loff_t *ppos) -{ - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - ssize_t res, buf_size; - int value, freq, subscribed, cmd_len; - struct cmd_ctrl_node *pcmdnode; - struct cmd_ds_command *pcmdptr; - struct cmd_ds_802_11_subscribe_event *event; - struct mrvlietypes_snrthreshold *snr_threshold; - void *response_buf; - u16 event_bitmap; - u8 *ptr; - unsigned long addr = get_zeroed_page(GFP_KERNEL); - char *buf = (char *)addr; - buf_size = min(count, len - 1); - if (copy_from_user(buf, userbuf, buf_size)) { - res = -EFAULT; - goto out_unlock; - } - res = sscanf(buf, "%d %d %d", &value, &freq, &subscribed); - if (res != 3) { - res = -EFAULT; - goto out_unlock; - } - event_bitmap = libertas_get_events_bitmap(priv); - res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); - if (res < 0) - goto out_unlock; - event = &pcmdptr->params.subscribe_event; - event->action = cpu_to_le16(CMD_ACT_SET); - pcmdptr->size = cpu_to_le16(S_DS_GEN + - sizeof(struct cmd_ds_802_11_subscribe_event) + - sizeof(struct mrvlietypes_snrthreshold)); - cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); - ptr = (u8*) pcmdptr+cmd_len; - snr_threshold = (struct mrvlietypes_snrthreshold *)(ptr); - snr_threshold->header.type = cpu_to_le16(TLV_TYPE_SNR_HIGH); - snr_threshold->header.len = cpu_to_le16(2); - snr_threshold->snrvalue = value; - snr_threshold->snrfreq = freq; - event_bitmap |= subscribed ? 0x0020 : 0x0; - event->events = cpu_to_le16(event_bitmap); - - libertas_queue_cmd(adapter, pcmdnode, 1); - wake_up_interruptible(&priv->waitq); - - /* Sleep until response is generated by FW */ - wait_event_interruptible(pcmdnode->cmdwait_q, - pcmdnode->cmdwaitqwoken); - - pcmdptr = response_buf; - - if (pcmdptr->result) { - lbs_pr_err("%s: fail, result=%d\n", __func__, - le16_to_cpu(pcmdptr->result)); - kfree(response_buf); - free_page(addr); - return 0; - } - if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { - lbs_pr_err("command response incorrect!\n"); - kfree(response_buf); - free_page(addr); - return 0; - } - res = count; -out_unlock: - free_page(addr); - return res; -} -static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf, +static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct wlan_offset_value offval; + struct lbs_private *priv = file->private_data; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -1375,7 +619,7 @@ static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf, offval.offset = priv->mac_offset; offval.value = 0; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_MAC_REG_ACCESS, 0, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1387,11 +631,11 @@ static ssize_t libertas_rdmac_read(struct file *file, char __user *userbuf, return ret; } -static ssize_t libertas_rdmac_write(struct file *file, +static ssize_t lbs_rdmac_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1408,15 +652,15 @@ out_unlock: return res; } -static ssize_t libertas_wrmac_write(struct file *file, +static ssize_t lbs_wrmac_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct wlan_offset_value offval; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1433,7 +677,7 @@ static ssize_t libertas_wrmac_write(struct file *file, offval.offset = offset; offval.value = value; - res = libertas_prepare_and_send_command(priv, + res = lbs_prepare_and_send_command(priv, CMD_MAC_REG_ACCESS, 1, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1444,12 +688,12 @@ out_unlock: return res; } -static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf, +static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct wlan_offset_value offval; + struct lbs_private *priv = file->private_data; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -1458,7 +702,7 @@ static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf, offval.offset = priv->bbp_offset; offval.value = 0; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_BBP_REG_ACCESS, 0, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1471,11 +715,11 @@ static ssize_t libertas_rdbbp_read(struct file *file, char __user *userbuf, return ret; } -static ssize_t libertas_rdbbp_write(struct file *file, +static ssize_t lbs_rdbbp_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1492,15 +736,15 @@ out_unlock: return res; } -static ssize_t libertas_wrbbp_write(struct file *file, +static ssize_t lbs_wrbbp_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct wlan_offset_value offval; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1517,7 +761,7 @@ static ssize_t libertas_wrbbp_write(struct file *file, offval.offset = offset; offval.value = value; - res = libertas_prepare_and_send_command(priv, + res = lbs_prepare_and_send_command(priv, CMD_BBP_REG_ACCESS, 1, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1528,12 +772,12 @@ out_unlock: return res; } -static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf, +static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; - wlan_adapter *adapter = priv->adapter; - struct wlan_offset_value offval; + struct lbs_private *priv = file->private_data; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_offset_value offval; ssize_t pos = 0; int ret; unsigned long addr = get_zeroed_page(GFP_KERNEL); @@ -1542,7 +786,7 @@ static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf, offval.offset = priv->rf_offset; offval.value = 0; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_RF_REG_ACCESS, 0, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1555,11 +799,11 @@ static ssize_t libertas_rdrf_read(struct file *file, char __user *userbuf, return ret; } -static ssize_t libertas_rdrf_write(struct file *file, +static ssize_t lbs_rdrf_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1576,15 +820,15 @@ out_unlock: return res; } -static ssize_t libertas_wrrf_write(struct file *file, +static ssize_t lbs_wrrf_write(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { - wlan_private *priv = file->private_data; + struct lbs_private *priv = file->private_data; ssize_t res, buf_size; u32 offset, value; - struct wlan_offset_value offval; + struct lbs_offset_value offval; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; @@ -1601,7 +845,7 @@ static ssize_t libertas_wrrf_write(struct file *file, offval.offset = offset; offval.value = value; - res = libertas_prepare_and_send_command(priv, + res = lbs_prepare_and_send_command(priv, CMD_RF_REG_ACCESS, 1, CMD_OPTION_WAITFORRSP, 0, &offval); mdelay(10); @@ -1619,69 +863,69 @@ out_unlock: .write = (fwrite), \ } -struct libertas_debugfs_files { +struct lbs_debugfs_files { char *name; int perm; struct file_operations fops; }; -static struct libertas_debugfs_files debugfs_files[] = { - { "info", 0444, FOPS(libertas_dev_info, write_file_dummy), }, - { "getscantable", 0444, FOPS(libertas_getscantable, +static struct lbs_debugfs_files debugfs_files[] = { + { "info", 0444, FOPS(lbs_dev_info, write_file_dummy), }, + { "getscantable", 0444, FOPS(lbs_getscantable, write_file_dummy), }, - { "sleepparams", 0644, FOPS(libertas_sleepparams_read, - libertas_sleepparams_write), }, - { "extscan", 0600, FOPS(NULL, libertas_extscan), }, - { "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), }, + { "sleepparams", 0644, FOPS(lbs_sleepparams_read, + lbs_sleepparams_write), }, + { "extscan", 0600, FOPS(NULL, lbs_extscan), }, + { "setuserscan", 0600, FOPS(NULL, lbs_setuserscan), }, }; -static struct libertas_debugfs_files debugfs_events_files[] = { - {"low_rssi", 0644, FOPS(libertas_lowrssi_read, - libertas_lowrssi_write), }, - {"low_snr", 0644, FOPS(libertas_lowsnr_read, - libertas_lowsnr_write), }, - {"failure_count", 0644, FOPS(libertas_failcount_read, - libertas_failcount_write), }, - {"beacon_missed", 0644, FOPS(libertas_bcnmiss_read, - libertas_bcnmiss_write), }, - {"high_rssi", 0644, FOPS(libertas_highrssi_read, - libertas_highrssi_write), }, - {"high_snr", 0644, FOPS(libertas_highsnr_read, - libertas_highsnr_write), }, +static struct lbs_debugfs_files debugfs_events_files[] = { + {"low_rssi", 0644, FOPS(lbs_lowrssi_read, + lbs_lowrssi_write), }, + {"low_snr", 0644, FOPS(lbs_lowsnr_read, + lbs_lowsnr_write), }, + {"failure_count", 0644, FOPS(lbs_failcount_read, + lbs_failcount_write), }, + {"beacon_missed", 0644, FOPS(lbs_bcnmiss_read, + lbs_bcnmiss_write), }, + {"high_rssi", 0644, FOPS(lbs_highrssi_read, + lbs_highrssi_write), }, + {"high_snr", 0644, FOPS(lbs_highsnr_read, + lbs_highsnr_write), }, }; -static struct libertas_debugfs_files debugfs_regs_files[] = { - {"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), }, - {"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), }, - {"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), }, - {"wrbbp", 0600, FOPS(NULL, libertas_wrbbp_write), }, - {"rdrf", 0644, FOPS(libertas_rdrf_read, libertas_rdrf_write), }, - {"wrrf", 0600, FOPS(NULL, libertas_wrrf_write), }, +static struct lbs_debugfs_files debugfs_regs_files[] = { + {"rdmac", 0644, FOPS(lbs_rdmac_read, lbs_rdmac_write), }, + {"wrmac", 0600, FOPS(NULL, lbs_wrmac_write), }, + {"rdbbp", 0644, FOPS(lbs_rdbbp_read, lbs_rdbbp_write), }, + {"wrbbp", 0600, FOPS(NULL, lbs_wrbbp_write), }, + {"rdrf", 0644, FOPS(lbs_rdrf_read, lbs_rdrf_write), }, + {"wrrf", 0600, FOPS(NULL, lbs_wrrf_write), }, }; -void libertas_debugfs_init(void) +void lbs_debugfs_init(void) { - if (!libertas_dir) - libertas_dir = debugfs_create_dir("libertas_wireless", NULL); + if (!lbs_dir) + lbs_dir = debugfs_create_dir("lbs_wireless", NULL); return; } -void libertas_debugfs_remove(void) +void lbs_debugfs_remove(void) { - if (libertas_dir) - debugfs_remove(libertas_dir); + if (lbs_dir) + debugfs_remove(lbs_dir); return; } -void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev) +void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) { int i; - struct libertas_debugfs_files *files; - if (!libertas_dir) + struct lbs_debugfs_files *files; + if (!lbs_dir) goto exit; - priv->debugfs_dir = debugfs_create_dir(dev->name, libertas_dir); + priv->debugfs_dir = debugfs_create_dir(dev->name, lbs_dir); if (!priv->debugfs_dir) goto exit; @@ -1721,13 +965,13 @@ void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev) } #ifdef PROC_DEBUG - libertas_debug_init(priv, dev); + lbs_debug_init(priv, dev); #endif exit: return; } -void libertas_debugfs_remove_one(wlan_private *priv) +void lbs_debugfs_remove_one(struct lbs_private *priv) { int i; @@ -1754,8 +998,8 @@ void libertas_debugfs_remove_one(wlan_private *priv) #ifdef PROC_DEBUG -#define item_size(n) (FIELD_SIZEOF(wlan_adapter, n)) -#define item_addr(n) (offsetof(wlan_adapter, n)) +#define item_size(n) (FIELD_SIZEOF(struct lbs_adapter, n)) +#define item_addr(n) (offsetof(struct lbs_adapter, n)) struct debug_data { @@ -1764,7 +1008,7 @@ struct debug_data { size_t addr; }; -/* To debug any member of wlan_adapter, simply add one line here. +/* To debug any member of struct lbs_adapter, simply add one line here. */ static struct debug_data items[] = { {"intcounter", item_size(intcounter), item_addr(intcounter)}, @@ -1785,7 +1029,7 @@ static int num_of_items = ARRAY_SIZE(items); * @param data data to output * @return number of output data */ -static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf, +static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { int val = 0; @@ -1829,7 +1073,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf, * @param data data to write * @return number of data */ -static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf, +static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, size_t cnt, loff_t *ppos) { int r, i; @@ -1881,21 +1125,21 @@ static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf, return (ssize_t)cnt; } -static struct file_operations libertas_debug_fops = { +static struct file_operations lbs_debug_fops = { .owner = THIS_MODULE, .open = open_file_generic, - .write = wlan_debugfs_write, - .read = wlan_debugfs_read, + .write = lbs_debugfs_write, + .read = lbs_debugfs_read, }; /** * @brief create debug proc file * - * @param priv pointer wlan_private + * @param priv pointer struct lbs_private * @param dev pointer net_device * @return N/A */ -static void libertas_debug_init(wlan_private * priv, struct net_device *dev) +static void lbs_debug_init(struct lbs_private *priv, struct net_device *dev) { int i; @@ -1907,7 +1151,6 @@ static void libertas_debug_init(wlan_private * priv, struct net_device *dev) priv->debugfs_debug = debugfs_create_file("debug", 0644, priv->debugfs_dir, &items[0], - &libertas_debug_fops); + &lbs_debug_fops); } #endif - diff --git a/drivers/net/wireless/libertas/debugfs.h b/drivers/net/wireless/libertas/debugfs.h index 880a11b..f2b9c7f 100644 --- a/drivers/net/wireless/libertas/debugfs.h +++ b/drivers/net/wireless/libertas/debugfs.h @@ -1,6 +1,10 @@ -void libertas_debugfs_init(void); -void libertas_debugfs_remove(void); +#ifndef _LBS_DEBUGFS_H_ +#define _LBS_DEBUGFS_H_ -void libertas_debugfs_init_one(wlan_private *priv, struct net_device *dev); -void libertas_debugfs_remove_one(wlan_private *priv); +void lbs_debugfs_init(void); +void lbs_debugfs_remove(void); +void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev); +void lbs_debugfs_remove_one(struct lbs_private *priv); + +#endif diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 87fea9d..74187f3 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -3,80 +3,88 @@ * functions defined in other source files */ -#ifndef _WLAN_DECL_H_ -#define _WLAN_DECL_H_ +#ifndef _LBS_DECL_H_ +#define _LBS_DECL_H_ #include #include "defs.h" /** Function Prototype Declaration */ -struct wlan_private; +struct lbs_private; +struct lbs_adapter; struct sk_buff; struct net_device; -int libertas_set_mac_packet_filter(wlan_private * priv); +int lbs_set_mac_packet_filter(struct lbs_private *priv); -void libertas_send_tx_feedback(wlan_private * priv); +void lbs_send_tx_feedback(struct lbs_private *priv); -int libertas_free_cmd_buffer(wlan_private * priv); +int lbs_free_cmd_buffer(struct lbs_private *priv); struct cmd_ctrl_node; -struct cmd_ctrl_node *libertas_get_free_cmd_ctrl_node(wlan_private * priv); - -void libertas_set_cmd_ctrl_node(wlan_private * priv, - struct cmd_ctrl_node *ptempnode, - u32 cmd_oid, u16 wait_option, void *pdata_buf); - -int libertas_prepare_and_send_command(wlan_private * priv, - u16 cmd_no, - u16 cmd_action, - u16 wait_option, u32 cmd_oid, void *pdata_buf); - -void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u8 addtail); - -int libertas_allocate_cmd_buffer(wlan_private * priv); -int libertas_execute_next_command(wlan_private * priv); -int libertas_process_event(wlan_private * priv); -void libertas_interrupt(struct net_device *); -int libertas_set_radio_control(wlan_private * priv); -u32 libertas_fw_index_to_data_rate(u8 index); -u8 libertas_data_rate_to_fw_index(u32 rate); -void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen); - -void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb); +struct cmd_ctrl_node *lbs_get_free_cmd_ctrl_node(struct lbs_private *priv); + +void lbs_set_cmd_ctrl_node(struct lbs_private *priv, + struct cmd_ctrl_node *ptempnode, + u32 cmd_oid, u16 wait_option, void *pdata_buf); + +int lbs_prepare_and_send_command(struct lbs_private *priv, + u16 cmd_no, + u16 cmd_action, + u16 wait_option, u32 cmd_oid, void *pdata_buf); + +void lbs_queue_cmd(struct lbs_adapter *adapter, + struct cmd_ctrl_node *cmdnode, + u8 addtail); + +int lbs_allocate_cmd_buffer(struct lbs_private *priv); +int lbs_execute_next_command(struct lbs_private *priv); +int lbs_process_event(struct lbs_private *priv); +void lbs_interrupt(struct net_device *); +int lbs_set_radio_control(struct lbs_private *priv); +u32 lbs_fw_index_to_data_rate(u8 index); +u8 lbs_data_rate_to_fw_index(u32 rate); +void lbs_get_fwversion(struct lbs_adapter *adapter, + char *fwversion, + int maxlen); + +void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb); /** The proc fs interface */ -int libertas_process_rx_command(wlan_private * priv); -int libertas_process_tx(wlan_private * priv, struct sk_buff *skb); -void __libertas_cleanup_and_insert_cmd(wlan_private * priv, - struct cmd_ctrl_node *ptempcmd); +int lbs_process_rx_command(struct lbs_private *priv); +int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb); +void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv, + struct cmd_ctrl_node *ptempcmd); -int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band); +int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band); -int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *); +int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *); -void libertas_ps_sleep(wlan_private * priv, int wait_option); -void libertas_ps_confirm_sleep(wlan_private * priv, u16 psmode); -void libertas_ps_wakeup(wlan_private * priv, int wait_option); +void lbs_ps_sleep(struct lbs_private *priv, int wait_option); +void lbs_ps_confirm_sleep(struct lbs_private *priv, u16 psmode); +void lbs_ps_wakeup(struct lbs_private *priv, int wait_option); -void libertas_tx_runqueue(wlan_private *priv); +void lbs_tx_runqueue(struct lbs_private *priv); -struct chan_freq_power *libertas_find_cfp_by_band_and_channel( - wlan_adapter * adapter, u8 band, u16 channel); +struct chan_freq_power *lbs_find_cfp_by_band_and_channel( + struct lbs_adapter *adapter, + u8 band, + u16 channel); -void libertas_mac_event_disconnected(wlan_private * priv); +void lbs_mac_event_disconnected(struct lbs_private *priv); -void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str); +void lbs_send_iwevcustom_event(struct lbs_private *priv, s8 *str); /* main.c */ -struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, - int *cfp_no); -wlan_private *libertas_add_card(void *card, struct device *dmdev); -int libertas_remove_card(wlan_private *priv); -int libertas_start_card(wlan_private *priv); -int libertas_stop_card(wlan_private *priv); -int libertas_add_mesh(wlan_private *priv, struct device *dev); -void libertas_remove_mesh(wlan_private *priv); -int libertas_reset_device(wlan_private *priv); - -#endif /* _WLAN_DECL_H_ */ +struct chan_freq_power *lbs_get_region_cfp_table(u8 region, + u8 band, + int *cfp_no); +struct lbs_private *lbs_add_card(void *card, struct device *dmdev); +int lbs_remove_card(struct lbs_private *priv); +int lbs_start_card(struct lbs_private *priv); +int lbs_stop_card(struct lbs_private *priv); +int lbs_add_mesh(struct lbs_private *priv, struct device *dev); +void lbs_remove_mesh(struct lbs_private *priv); +int lbs_reset_device(struct lbs_private *priv); + +#endif diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 3a0c9be..8242384 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -2,8 +2,8 @@ * This header file contains global constant/enum definitions, * global variable declaration. */ -#ifndef _WLAN_DEFS_H_ -#define _WLAN_DEFS_H_ +#ifndef _LBS_DEFS_H_ +#define _LBS_DEFS_H_ #include @@ -41,11 +41,11 @@ #define LBS_DEB_HEX 0x00200000 #define LBS_DEB_SDIO 0x00400000 -extern unsigned int libertas_debug; +extern unsigned int lbs_debug; #ifdef DEBUG #define LBS_DEB_LL(grp, grpnam, fmt, args...) \ -do { if ((libertas_debug & (grp)) == (grp)) \ +do { if ((lbs_debug & (grp)) == (grp)) \ printk(KERN_DEBUG DRV_NAME grpnam "%s: " fmt, \ in_interrupt() ? " (INT)" : "", ## args); } while (0) #else @@ -96,8 +96,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in int i = 0; if (len && - (libertas_debug & LBS_DEB_HEX) && - (libertas_debug & grp)) + (lbs_debug & LBS_DEB_HEX) && + (lbs_debug & grp)) { for (i = 1; i <= len; i++) { if ((i & 0xf) == 1) { @@ -138,7 +138,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define MRVDRV_ASSOCIATION_TIME_OUT 255 #define MRVDRV_SNAP_HEADER_LEN 8 -#define WLAN_UPLD_SIZE 2312 +#define LBS_UPLD_SIZE 2312 #define DEV_NAME_LEN 32 /** Misc constants */ @@ -262,12 +262,10 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define UNSET_MESH_FRAME(x) (x->cb[6]=0) /** Global Variable Declaration */ -typedef struct _wlan_private wlan_private; -typedef struct _wlan_adapter wlan_adapter; -extern const char libertas_driver_version[]; -extern u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE]; +extern const char lbs_driver_version[]; +extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE]; -extern u8 libertas_bg_rates[MAX_RATES]; +extern u8 lbs_bg_rates[MAX_RATES]; /** ENUM definition*/ /** SNRNF_TYPE */ @@ -284,13 +282,13 @@ enum SNRNF_DATA { MAX_TYPE_AVG }; -/** WLAN_802_11_POWER_MODE */ -enum WLAN_802_11_POWER_MODE { - WLAN802_11POWERMODECAM, - WLAN802_11POWERMODEMAX_PSP, - WLAN802_11POWERMODEFAST_PSP, +/** LBS_802_11_POWER_MODE */ +enum LBS_802_11_POWER_MODE { + LBS802_11POWERMODECAM, + LBS802_11POWERMODEMAX_PSP, + LBS802_11POWERMODEFAST_PSP, /*not a real mode, defined as an upper bound */ - WLAN802_11POWEMODEMAX + LBS802_11POWEMODEMAX }; /** PS_STATE */ @@ -308,16 +306,16 @@ enum DNLD_STATE { DNLD_CMD_SENT }; -/** WLAN_MEDIA_STATE */ -enum WLAN_MEDIA_STATE { - LIBERTAS_CONNECTED, - LIBERTAS_DISCONNECTED +/** LBS_MEDIA_STATE */ +enum LBS_MEDIA_STATE { + LBS_CONNECTED, + LBS_DISCONNECTED }; -/** WLAN_802_11_PRIVACY_FILTER */ -enum WLAN_802_11_PRIVACY_FILTER { - WLAN802_11PRIVFILTERACCEPTALL, - WLAN802_11PRIVFILTER8021XWEP +/** LBS_802_11_PRIVACY_FILTER */ +enum LBS_802_11_PRIVACY_FILTER { + LBS802_11PRIVFILTERACCEPTALL, + LBS802_11PRIVFILTER8021XWEP }; /** mv_ms_type */ @@ -382,4 +380,4 @@ enum SNMP_MIB_VALUE_e { #define FWT_DEFAULT_SLEEPMODE 0 #define FWT_DEFAULT_SNR 0 -#endif /* _WLAN_DEFS_H_ */ +#endif diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 1fb807a..1efea63 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -1,10 +1,10 @@ /** * This file contains definitions and data structures specific * to Marvell 802.11 NIC. It contains the Device Information - * structure wlan_adapter. + * structure struct lbs_adapter. */ -#ifndef _WLAN_DEV_H_ -#define _WLAN_DEV_H_ +#ifndef _LBS_DEV_H_ +#define _LBS_DEV_H_ #include #include @@ -15,7 +15,7 @@ #include "defs.h" #include "scan.h" -extern struct ethtool_ops libertas_ethtool_ops; +extern struct ethtool_ops lbs_ethtool_ops; #define MAX_BSSID_PER_CHANNEL 16 @@ -53,7 +53,7 @@ struct region_channel { struct chan_freq_power *CFP; }; -struct wlan_802_11_security { +struct lbs_802_11_security { u8 WPAenabled; u8 WPA2enabled; u8 wep_enabled; @@ -87,7 +87,7 @@ struct sleep_params { }; /* Mesh statistics */ -struct wlan_mesh_stats { +struct lbs_mesh_stats { u32 fwd_bcast_cnt; /* Fwd: Broadcast counter */ u32 fwd_unicast_cnt; /* Fwd: Unicast counter */ u32 fwd_drop_ttl; /* Fwd: TTL zero */ @@ -99,7 +99,7 @@ struct wlan_mesh_stats { }; /** Private structure for the MV device */ -struct _wlan_private { +struct lbs_private { int open; int mesh_open; int infra_open; @@ -109,7 +109,7 @@ struct _wlan_private { char name[DEV_NAME_LEN]; void *card; - wlan_adapter *adapter; + struct lbs_adapter *adapter; struct net_device *dev; struct net_device_stats stats; @@ -118,7 +118,7 @@ struct _wlan_private { struct ieee80211_device *ieee; struct iw_statistics wstats; - struct wlan_mesh_stats mstats; + struct lbs_mesh_stats mstats; struct dentry *debugfs_dir; struct dentry *debugfs_debug; struct dentry *debugfs_files[6]; @@ -136,7 +136,7 @@ struct _wlan_private { /** Upload length */ u32 upld_len; /* Upload buffer */ - u8 upld_buf[WLAN_UPLD_SIZE]; + u8 upld_buf[LBS_UPLD_SIZE]; /* Download sent: bit0 1/0=data_sent/data_tx_done, bit1 1/0=cmd_sent/cmd_tx_done, @@ -155,9 +155,9 @@ struct _wlan_private { struct work_struct sync_channel; /** Hardware access */ - int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb); - int (*hw_get_int_status) (wlan_private * priv, u8 *); - int (*hw_read_event_cause) (wlan_private *); + int (*hw_host_to_card) (struct lbs_private *priv, u8 type, u8 *payload, u16 nb); + int (*hw_get_int_status) (struct lbs_private *priv, u8 *); + int (*hw_read_event_cause) (struct lbs_private *); }; /** Association request @@ -194,7 +194,7 @@ struct assoc_request { struct enc_key wpa_mcast_key; struct enc_key wpa_unicast_key; - struct wlan_802_11_security secinfo; + struct lbs_802_11_security secinfo; /** WPA Information Elements*/ u8 wpa_ie[MAX_WPA_IE_LEN]; @@ -205,7 +205,7 @@ struct assoc_request { }; /** Wlan adapter data structure*/ -struct _wlan_adapter { +struct lbs_adapter { /** STATUS variables */ u8 fwreleasenumber[4]; u32 fwcapinfo; @@ -213,7 +213,7 @@ struct _wlan_adapter { struct mutex lock; - u8 tmptxbuf[WLAN_UPLD_SIZE]; + u8 tmptxbuf[LBS_UPLD_SIZE]; /* protected by hard_start_xmit serialization */ /** command-related variables */ @@ -263,6 +263,8 @@ struct _wlan_adapter { struct list_head network_free_list; struct bss_descriptor *networks; + u16 beacon_period; + u8 beacon_enable; u8 adhoccreate; /** capability Info used in Association, start, join */ @@ -291,6 +293,7 @@ struct _wlan_adapter { /** NIC Operation characteristics */ u16 currentpacketfilter; u32 connect_status; + u32 mesh_connect_status; u16 regioncode; u16 txpowerlevel; @@ -302,13 +305,13 @@ struct _wlan_adapter { u32 psstate; u8 needtowakeup; - struct PS_CMD_ConfirmSleep libertas_ps_confirm_sleep; + struct PS_CMD_ConfirmSleep lbs_ps_confirm_sleep; struct assoc_request * pending_assoc_req; struct assoc_request * in_progress_assoc_req; /** Encryption parameter */ - struct wlan_802_11_security secinfo; + struct lbs_802_11_security secinfo; /** WEP keys */ struct enc_key wep_keys[4]; @@ -350,7 +353,7 @@ struct _wlan_adapter { struct region_channel universal_channel[MAX_REGION_CHANNEL_NUM]; /** 11D and Domain Regulatory Data */ - struct wlan_802_11d_domain_reg domainreg; + struct lbs_802_11d_domain_reg domainreg; struct parsed_region_chan_11d parsed_region_chan; /** FSM variable for 11d support */ @@ -358,7 +361,7 @@ struct _wlan_adapter { /** MISCELLANEOUS */ u8 *prdeeprom; - struct wlan_offset_value offsetvalue; + struct lbs_offset_value offsetvalue; struct cmd_ds_802_11_get_log logmsg; @@ -368,4 +371,4 @@ struct _wlan_adapter { u8 last_scanned_channel; }; -#endif /* _WLAN_DEV_H_ */ +#endif diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c index 3dae152..f32fb00 100644 --- a/drivers/net/wireless/libertas/ethtool.c +++ b/drivers/net/wireless/libertas/ethtool.c @@ -19,35 +19,35 @@ static const char * mesh_stat_strings[]= { "tx_failed_cnt" }; -static void libertas_ethtool_get_drvinfo(struct net_device *dev, +static void lbs_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - wlan_private *priv = (wlan_private *) dev->priv; + struct lbs_private *priv = (struct lbs_private *) dev->priv; char fwver[32]; - libertas_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1); + lbs_get_fwversion(priv->adapter, fwver, sizeof(fwver) - 1); strcpy(info->driver, "libertas"); - strcpy(info->version, libertas_driver_version); + strcpy(info->version, lbs_driver_version); strcpy(info->fw_version, fwver); } /* All 8388 parts have 16KiB EEPROM size at the time of writing. * In case that changes this needs fixing. */ -#define LIBERTAS_EEPROM_LEN 16384 +#define LBS_EEPROM_LEN 16384 -static int libertas_ethtool_get_eeprom_len(struct net_device *dev) +static int lbs_ethtool_get_eeprom_len(struct net_device *dev) { - return LIBERTAS_EEPROM_LEN; + return LBS_EEPROM_LEN; } -static int libertas_ethtool_get_eeprom(struct net_device *dev, +static int lbs_ethtool_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, u8 * bytes) { - wlan_private *priv = (wlan_private *) dev->priv; - wlan_adapter *adapter = priv->adapter; - struct wlan_ioctl_regrdwr regctrl; + struct lbs_private *priv = (struct lbs_private *) dev->priv; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_ioctl_regrdwr regctrl; char *ptr; int ret; @@ -55,7 +55,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, regctrl.offset = eeprom->offset; regctrl.NOB = eeprom->len; - if (eeprom->offset + eeprom->len > LIBERTAS_EEPROM_LEN) + if (eeprom->offset + eeprom->len > LBS_EEPROM_LEN) return -EINVAL; // mutex_lock(&priv->mutex); @@ -70,7 +70,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, lbs_deb_ethtool("action:%d offset: %x NOB: %02x\n", regctrl.action, regctrl.offset, regctrl.NOB); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_EEPROM_ACCESS, regctrl.action, CMD_OPTION_WAITFORRSP, 0, @@ -87,7 +87,7 @@ static int libertas_ethtool_get_eeprom(struct net_device *dev, ptr = (char *)adapter->prdeeprom; /* skip the command header, but include the "value" u32 variable */ - ptr = ptr + sizeof(struct wlan_ioctl_regrdwr) - 4; + ptr = ptr + sizeof(struct lbs_ioctl_regrdwr) - 4; /* * Return the result back to the user @@ -105,17 +105,17 @@ done: return ret; } -static void libertas_ethtool_get_stats(struct net_device * dev, +static void lbs_ethtool_get_stats(struct net_device * dev, struct ethtool_stats * stats, u64 * data) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; struct cmd_ds_mesh_access mesh_access; int ret; lbs_deb_enter(LBS_DEB_ETHTOOL); /* Get Mesh Statistics */ - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_MESH_ACCESS, CMD_ACT_MESH_GET_STATS, CMD_OPTION_WAITFORRSP, 0, &mesh_access); @@ -143,7 +143,7 @@ static void libertas_ethtool_get_stats(struct net_device * dev, lbs_deb_enter(LBS_DEB_ETHTOOL); } -static int libertas_ethtool_get_sset_count(struct net_device * dev, int sset) +static int lbs_ethtool_get_sset_count(struct net_device * dev, int sset) { switch (sset) { case ETH_SS_STATS: @@ -153,7 +153,7 @@ static int libertas_ethtool_get_sset_count(struct net_device * dev, int sset) } } -static void libertas_ethtool_get_strings (struct net_device * dev, +static void lbs_ethtool_get_strings(struct net_device *dev, u32 stringset, u8 * s) { @@ -173,12 +173,12 @@ static void libertas_ethtool_get_strings (struct net_device * dev, lbs_deb_enter(LBS_DEB_ETHTOOL); } -struct ethtool_ops libertas_ethtool_ops = { - .get_drvinfo = libertas_ethtool_get_drvinfo, - .get_eeprom = libertas_ethtool_get_eeprom, - .get_eeprom_len = libertas_ethtool_get_eeprom_len, - .get_sset_count = libertas_ethtool_get_sset_count, - .get_ethtool_stats = libertas_ethtool_get_stats, - .get_strings = libertas_ethtool_get_strings, +struct ethtool_ops lbs_ethtool_ops = { + .get_drvinfo = lbs_ethtool_get_drvinfo, + .get_eeprom = lbs_ethtool_get_eeprom, + .get_eeprom_len = lbs_ethtool_get_eeprom_len, + .get_sset_count = lbs_ethtool_get_sset_count, + .get_ethtool_stats = lbs_ethtool_get_stats, + .get_strings = lbs_ethtool_get_strings, }; diff --git a/drivers/net/wireless/libertas/host.h b/drivers/net/wireless/libertas/host.h index b37ddbc..4828bbf 100644 --- a/drivers/net/wireless/libertas/host.h +++ b/drivers/net/wireless/libertas/host.h @@ -2,8 +2,8 @@ * This file contains definitions of WLAN commands. */ -#ifndef _HOST_H_ -#define _HOST_H_ +#ifndef _LBS_HOST_H_ +#define _LBS_HOST_H_ /** PUBLIC DEFINITIONS */ #define DEFAULT_AD_HOC_CHANNEL 6 @@ -116,6 +116,8 @@ #define CMD_SET_BOOT2_VER 0x00a5 +#define CMD_802_11_BEACON_CTRL 0x00b0 + /* For the IEEE Power Save */ #define CMD_SUBCMD_ENTER_PS 0x0030 #define CMD_SUBCMD_EXIT_PS 0x0031 @@ -178,6 +180,14 @@ #define CMD_TYPE_SHORT_PREAMBLE 0x0002 #define CMD_TYPE_LONG_PREAMBLE 0x0003 +/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */ +#define CMD_SUBSCRIBE_RSSI_LOW 0x0001 +#define CMD_SUBSCRIBE_SNR_LOW 0x0002 +#define CMD_SUBSCRIBE_FAILCOUNT 0x0004 +#define CMD_SUBSCRIBE_BCNMISS 0x0008 +#define CMD_SUBSCRIBE_RSSI_HIGH 0x0010 +#define CMD_SUBSCRIBE_SNR_HIGH 0x0020 + #define TURN_ON_RF 0x01 #define RADIO_ON 0x01 #define RADIO_OFF 0x00 @@ -264,27 +274,35 @@ enum cmd_mesh_access_opts { }; /** Card Event definition */ -#define MACREG_INT_CODE_TX_PPA_FREE 0x00000000 -#define MACREG_INT_CODE_TX_DMA_DONE 0x00000001 -#define MACREG_INT_CODE_LINK_LOSE_W_SCAN 0x00000002 -#define MACREG_INT_CODE_LINK_LOSE_NO_SCAN 0x00000003 -#define MACREG_INT_CODE_LINK_SENSED 0x00000004 -#define MACREG_INT_CODE_CMD_FINISHED 0x00000005 -#define MACREG_INT_CODE_MIB_CHANGED 0x00000006 -#define MACREG_INT_CODE_INIT_DONE 0x00000007 -#define MACREG_INT_CODE_DEAUTHENTICATED 0x00000008 -#define MACREG_INT_CODE_DISASSOCIATED 0x00000009 -#define MACREG_INT_CODE_PS_AWAKE 0x0000000a -#define MACREG_INT_CODE_PS_SLEEP 0x0000000b -#define MACREG_INT_CODE_MIC_ERR_MULTICAST 0x0000000d -#define MACREG_INT_CODE_MIC_ERR_UNICAST 0x0000000e -#define MACREG_INT_CODE_WM_AWAKE 0x0000000f -#define MACREG_INT_CODE_ADHOC_BCN_LOST 0x00000011 -#define MACREG_INT_CODE_RSSI_LOW 0x00000019 -#define MACREG_INT_CODE_SNR_LOW 0x0000001a -#define MACREG_INT_CODE_MAX_FAIL 0x0000001b -#define MACREG_INT_CODE_RSSI_HIGH 0x0000001c -#define MACREG_INT_CODE_SNR_HIGH 0x0000001d -#define MACREG_INT_CODE_MESH_AUTO_STARTED 0x00000023 - -#endif /* _HOST_H_ */ +#define MACREG_INT_CODE_TX_PPA_FREE 0 +#define MACREG_INT_CODE_TX_DMA_DONE 1 +#define MACREG_INT_CODE_LINK_LOST_W_SCAN 2 +#define MACREG_INT_CODE_LINK_LOST_NO_SCAN 3 +#define MACREG_INT_CODE_LINK_SENSED 4 +#define MACREG_INT_CODE_CMD_FINISHED 5 +#define MACREG_INT_CODE_MIB_CHANGED 6 +#define MACREG_INT_CODE_INIT_DONE 7 +#define MACREG_INT_CODE_DEAUTHENTICATED 8 +#define MACREG_INT_CODE_DISASSOCIATED 9 +#define MACREG_INT_CODE_PS_AWAKE 10 +#define MACREG_INT_CODE_PS_SLEEP 11 +#define MACREG_INT_CODE_MIC_ERR_MULTICAST 13 +#define MACREG_INT_CODE_MIC_ERR_UNICAST 14 +#define MACREG_INT_CODE_WM_AWAKE 15 +#define MACREG_INT_CODE_DEEP_SLEEP_AWAKE 16 +#define MACREG_INT_CODE_ADHOC_BCN_LOST 17 +#define MACREG_INT_CODE_HOST_AWAKE 18 +#define MACREG_INT_CODE_STOP_TX 19 +#define MACREG_INT_CODE_START_TX 20 +#define MACREG_INT_CODE_CHANNEL_SWITCH 21 +#define MACREG_INT_CODE_MEASUREMENT_RDY 22 +#define MACREG_INT_CODE_WMM_CHANGE 23 +#define MACREG_INT_CODE_BG_SCAN_REPORT 24 +#define MACREG_INT_CODE_RSSI_LOW 25 +#define MACREG_INT_CODE_SNR_LOW 26 +#define MACREG_INT_CODE_MAX_FAIL 27 +#define MACREG_INT_CODE_RSSI_HIGH 28 +#define MACREG_INT_CODE_SNR_HIGH 29 +#define MACREG_INT_CODE_MESH_AUTO_STARTED 35 + +#endif diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index e1045dc..614db6c 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h @@ -2,8 +2,8 @@ * This file contains the function prototypes, data structure * and defines for all the host/station commands */ -#ifndef __HOSTCMD__H -#define __HOSTCMD__H +#ifndef _LBS_HOSTCMD_H +#define _LBS_HOSTCMD_H #include #include "11d.h" @@ -86,13 +86,13 @@ struct cmd_ctrl_node { /* Generic structure to hold all key types. */ struct enc_key { u16 len; - u16 flags; /* KEY_INFO_* from wlan_defs.h */ - u16 type; /* KEY_TYPE_* from wlan_defs.h */ + u16 flags; /* KEY_INFO_* from defs.h */ + u16 type; /* KEY_TYPE_* from defs.h */ u8 key[32]; }; -/* wlan_offset_value */ -struct wlan_offset_value { +/* lbs_offset_value */ +struct lbs_offset_value { u32 offset; u32 value; }; @@ -151,6 +151,13 @@ struct cmd_ds_802_11_reset { struct cmd_ds_802_11_subscribe_event { __le16 action; __le16 events; + + /* A TLV to the CMD_802_11_SUBSCRIBE_EVENT command can contain a + * number of TLVs. From the v5.1 manual, those TLVs would add up to + * 40 bytes. However, future firmware might add additional TLVs, so I + * bump this up a bit. + */ + u8 tlv[128]; }; /* @@ -332,6 +339,12 @@ struct cmd_ds_802_11_radio_control { __le16 control; }; +struct cmd_ds_802_11_beacon_control { + __le16 action; + __le16 beacon_enable; + __le16 beacon_period; +}; + struct cmd_ds_802_11_sleep_params { /* ACT_GET/ACT_SET */ __le16 action; @@ -668,6 +681,7 @@ struct cmd_ds_command { struct cmd_ds_set_boot2_ver boot2_ver; struct cmd_ds_get_tsf gettsf; struct cmd_ds_802_11_subscribe_event subscribe_event; + struct cmd_ds_802_11_beacon_control bcn_ctrl; } params; } __attribute__ ((packed)); diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index ba4fc2b..5fadcc0 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -57,7 +57,7 @@ MODULE_LICENSE("GPL"); struct if_cs_card { struct pcmcia_device *p_dev; - wlan_private *priv; + struct lbs_private *priv; void __iomem *iobase; }; @@ -243,7 +243,7 @@ static inline void if_cs_disable_ints(struct if_cs_card *card) static irqreturn_t if_cs_interrupt(int irq, void *data) { - struct if_cs_card *card = (struct if_cs_card *)data; + struct if_cs_card *card = data; u16 int_cause; lbs_deb_enter(LBS_DEB_CS); @@ -263,7 +263,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) if (!card->priv->adapter->cur_cmd) wake_up_interruptible(&card->priv->waitq); - if (card->priv->adapter->connect_status == LIBERTAS_CONNECTED) + if (card->priv->adapter->connect_status == LBS_CONNECTED) netif_wake_queue(card->priv->dev); } @@ -271,7 +271,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) if_cs_write16(card, IF_CS_C_INT_CAUSE, int_cause & IF_CS_C_IC_MASK); } - libertas_interrupt(card->priv->dev); + lbs_interrupt(card->priv->dev); return IRQ_HANDLED; } @@ -286,7 +286,7 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) /* * Called from if_cs_host_to_card to send a command to the hardware */ -static int if_cs_send_cmd(wlan_private *priv, u8 *buf, u16 nb) +static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) { struct if_cs_card *card = (struct if_cs_card *)priv->card; int ret = -1; @@ -331,7 +331,7 @@ done: /* * Called from if_cs_host_to_card to send a data to the hardware */ -static void if_cs_send_data(wlan_private *priv, u8 *buf, u16 nb) +static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb) { struct if_cs_card *card = (struct if_cs_card *)priv->card; @@ -354,7 +354,7 @@ static void if_cs_send_data(wlan_private *priv, u8 *buf, u16 nb) /* * Get the command result out of the card. */ -static int if_cs_receive_cmdres(wlan_private *priv, u8* data, u32 *len) +static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len) { int ret = -1; u16 val; @@ -386,7 +386,7 @@ out: } -static struct sk_buff *if_cs_receive_data(wlan_private *priv) +static struct sk_buff *if_cs_receive_data(struct lbs_private *priv) { struct sk_buff *skb = NULL; u16 len; @@ -616,7 +616,10 @@ done: /********************************************************************/ /* Send commands or data packets to the card */ -static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) +static int if_cs_host_to_card(struct lbs_private *priv, + u8 type, + u8 *buf, + u16 nb) { int ret = -1; @@ -641,10 +644,10 @@ static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) } -static int if_cs_get_int_status(wlan_private *priv, u8 *ireg) +static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg) { struct if_cs_card *card = (struct if_cs_card *)priv->card; - //wlan_adapter *adapter = priv->adapter; + /* struct lbs_adapter *adapter = priv->adapter; */ int ret = 0; u16 int_cause; u8 *cmdbuf; @@ -668,7 +671,7 @@ sbi_get_int_status_exit: /* is there a data packet for us? */ if (*ireg & IF_CS_C_S_RX_UPLD_RDY) { struct sk_buff *skb = if_cs_receive_data(priv); - libertas_process_rxed_packet(priv, skb); + lbs_process_rxed_packet(priv, skb); *ireg &= ~IF_CS_C_S_RX_UPLD_RDY; } @@ -698,7 +701,7 @@ out: } -static int if_cs_read_event_cause(wlan_private *priv) +static int if_cs_read_event_cause(struct lbs_private *priv) { lbs_deb_enter(LBS_DEB_CS); @@ -746,7 +749,7 @@ static void if_cs_release(struct pcmcia_device *p_dev) static int if_cs_probe(struct pcmcia_device *p_dev) { int ret = -ENOMEM; - wlan_private *priv; + struct lbs_private *priv; struct if_cs_card *card; /* CIS parsing */ tuple_t tuple; @@ -856,7 +859,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out2; /* Make this card known to the libertas driver */ - priv = libertas_add_card(card, &p_dev->dev); + priv = lbs_add_card(card, &p_dev->dev); if (!priv) { ret = -ENOMEM; goto out2; @@ -885,7 +888,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) if_cs_enable_ints(card); /* And finally bring the card up */ - if (libertas_start_card(priv) != 0) { + if (lbs_start_card(priv) != 0) { lbs_pr_err("could not activate card\n"); goto out3; } @@ -894,7 +897,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) goto out; out3: - libertas_remove_card(priv); + lbs_remove_card(priv); out2: ioport_unmap(card->iobase); out1: @@ -917,8 +920,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev) lbs_deb_enter(LBS_DEB_CS); - libertas_stop_card(card->priv); - libertas_remove_card(card->priv); + lbs_stop_card(card->priv); + lbs_remove_card(card->priv); if_cs_disable_ints(card); if_cs_release(p_dev); kfree(card); @@ -939,7 +942,7 @@ static struct pcmcia_device_id if_cs_ids[] = { MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); -static struct pcmcia_driver libertas_driver = { +static struct pcmcia_driver lbs_driver = { .owner = THIS_MODULE, .drv = { .name = DRV_NAME, @@ -955,7 +958,7 @@ static int __init if_cs_init(void) int ret; lbs_deb_enter(LBS_DEB_CS); - ret = pcmcia_register_driver(&libertas_driver); + ret = pcmcia_register_driver(&lbs_driver); lbs_deb_leave(LBS_DEB_CS); return ret; } @@ -964,7 +967,7 @@ static int __init if_cs_init(void) static void __exit if_cs_exit(void) { lbs_deb_enter(LBS_DEB_CS); - pcmcia_unregister_driver(&libertas_driver); + pcmcia_unregister_driver(&lbs_driver); lbs_deb_leave(LBS_DEB_CS); } diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index b24425f..437f3dd 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -40,11 +40,11 @@ #include "dev.h" #include "if_sdio.h" -static char *libertas_helper_name = NULL; -module_param_named(helper_name, libertas_helper_name, charp, 0644); +static char *lbs_helper_name = NULL; +module_param_named(helper_name, lbs_helper_name, charp, 0644); -static char *libertas_fw_name = NULL; -module_param_named(fw_name, libertas_fw_name, charp, 0644); +static char *lbs_fw_name = NULL; +module_param_named(fw_name, lbs_fw_name, charp, 0644); static const struct sdio_device_id if_sdio_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) }, @@ -82,7 +82,7 @@ struct if_sdio_packet { struct if_sdio_card { struct sdio_func *func; - wlan_private *priv; + struct lbs_private *priv; int model; unsigned long ioport; @@ -154,7 +154,7 @@ static int if_sdio_handle_cmd(struct if_sdio_card *card, card->int_cause |= MRVDRV_CMD_UPLD_RDY; - libertas_interrupt(card->priv->dev); + lbs_interrupt(card->priv->dev); ret = 0; @@ -194,7 +194,7 @@ static int if_sdio_handle_data(struct if_sdio_card *card, memcpy(data, buffer, size); - libertas_process_rxed_packet(card->priv, skb); + lbs_process_rxed_packet(card->priv, skb); ret = 0; @@ -236,7 +236,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card, card->event = event; card->int_cause |= MRVDRV_CARDEVENT; - libertas_interrupt(card->priv->dev); + lbs_interrupt(card->priv->dev); spin_unlock_irqrestore(&card->priv->adapter->driver_lock, flags); @@ -694,7 +694,8 @@ out: /* Libertas callbacks */ /*******************************************************************/ -static int if_sdio_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) +static int if_sdio_host_to_card(struct lbs_private *priv, + u8 type, u8 *buf, u16 nb) { int ret; struct if_sdio_card *card; @@ -775,7 +776,7 @@ out: return ret; } -static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg) +static int if_sdio_get_int_status(struct lbs_private *priv, u8 *ireg) { struct if_sdio_card *card; @@ -791,7 +792,7 @@ static int if_sdio_get_int_status(wlan_private *priv, u8 *ireg) return 0; } -static int if_sdio_read_event_cause(wlan_private *priv) +static int if_sdio_read_event_cause(struct lbs_private *priv) { struct if_sdio_card *card; @@ -836,7 +837,7 @@ static void if_sdio_interrupt(struct sdio_func *func) */ if (cause & IF_SDIO_H_INT_DNLD) { if ((card->priv->dnld_sent == DNLD_DATA_SENT) && - (card->priv->adapter->connect_status == LIBERTAS_CONNECTED)) + (card->priv->adapter->connect_status == LBS_CONNECTED)) netif_wake_queue(card->priv->dev); card->priv->dnld_sent = DNLD_RES_RECEIVED; } @@ -857,7 +858,7 @@ static int if_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct if_sdio_card *card; - wlan_private *priv; + struct lbs_private *priv; int ret, i; unsigned int model; struct if_sdio_packet *packet; @@ -901,15 +902,15 @@ static int if_sdio_probe(struct sdio_func *func, card->helper = if_sdio_models[i].helper; card->firmware = if_sdio_models[i].firmware; - if (libertas_helper_name) { + if (lbs_helper_name) { lbs_deb_sdio("overriding helper firmware: %s\n", - libertas_helper_name); - card->helper = libertas_helper_name; + lbs_helper_name); + card->helper = lbs_helper_name; } - if (libertas_fw_name) { - lbs_deb_sdio("overriding firmware: %s\n", libertas_fw_name); - card->firmware = libertas_fw_name; + if (lbs_fw_name) { + lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); + card->firmware = lbs_fw_name; } sdio_claim_host(func); @@ -947,7 +948,7 @@ static int if_sdio_probe(struct sdio_func *func, if (ret) goto reclaim; - priv = libertas_add_card(card, &func->dev); + priv = lbs_add_card(card, &func->dev); if (!priv) { ret = -ENOMEM; goto reclaim; @@ -971,7 +972,7 @@ static int if_sdio_probe(struct sdio_func *func, if (ret) goto reclaim; - ret = libertas_start_card(priv); + ret = lbs_start_card(priv); if (ret) goto err_activate_card; @@ -1016,8 +1017,8 @@ static void if_sdio_remove(struct sdio_func *func) card->priv->adapter->surpriseremoved = 1; lbs_deb_sdio("call remove card\n"); - libertas_stop_card(card->priv); - libertas_remove_card(card->priv); + lbs_stop_card(card->priv); + lbs_remove_card(card->priv); flush_scheduled_work(); @@ -1048,7 +1049,7 @@ static struct sdio_driver if_sdio_driver = { /* Module functions */ /*******************************************************************/ -static int if_sdio_init_module(void) +static int __init if_sdio_init_module(void) { int ret = 0; @@ -1064,7 +1065,7 @@ static int if_sdio_init_module(void) return ret; } -static void if_sdio_exit_module(void) +static void __exit if_sdio_exit_module(void) { lbs_deb_enter(LBS_DEB_SDIO); diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h index dfcaea7..533bdfb 100644 --- a/drivers/net/wireless/libertas/if_sdio.h +++ b/drivers/net/wireless/libertas/if_sdio.h @@ -9,8 +9,8 @@ * your option) any later version. */ -#ifndef LIBERTAS_IF_SDIO_H -#define LIBERTAS_IF_SDIO_H +#ifndef _LBS_IF_SDIO_H +#define _LBS_IF_SDIO_H #define IF_SDIO_IOPORT 0x00 diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index cb59f46..4fce0ba 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -5,7 +5,6 @@ #include #include #include -#include #include #define DRV_NAME "usb8xxx" @@ -18,20 +17,8 @@ #define MESSAGE_HEADER_LEN 4 -static const char usbdriver_name[] = "usb8xxx"; -static u8 *default_fw_name = "usb8388.bin"; - -static char *libertas_fw_name = NULL; -module_param_named(fw_name, libertas_fw_name, charp, 0644); - -/* - * We need to send a RESET command to all USB devices before - * we tear down the USB connection. Otherwise we would not - * be able to re-init device the device if the module gets - * loaded again. This is a list of all initialized USB devices, - * for the reset code see if_usb_reset_device() -*/ -static LIST_HEAD(usb_devices); +static char *lbs_fw_name = "usb8388.bin"; +module_param_named(fw_name, lbs_fw_name, charp, 0644); static struct usb_device_id if_usb_table[] = { /* Enter the device signature inside */ @@ -45,9 +32,12 @@ MODULE_DEVICE_TABLE(usb, if_usb_table); static void if_usb_receive(struct urb *urb); static void if_usb_receive_fwload(struct urb *urb); static int if_usb_prog_firmware(struct usb_card_rec *cardp); -static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb); -static int if_usb_get_int_status(wlan_private * priv, u8 *); -static int if_usb_read_event_cause(wlan_private *); +static int if_usb_host_to_card(struct lbs_private *priv, + u8 type, + u8 *payload, + u16 nb); +static int if_usb_get_int_status(struct lbs_private *priv, u8 *); +static int if_usb_read_event_cause(struct lbs_private *); static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb); static void if_usb_free(struct usb_card_rec *cardp); static int if_usb_submit_rx_urb(struct usb_card_rec *cardp); @@ -65,7 +55,7 @@ static void if_usb_write_bulk_callback(struct urb *urb) /* handle the transmission complete validations */ if (urb->status == 0) { - wlan_private *priv = cardp->priv; + struct lbs_private *priv = cardp->priv; /* lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n"); @@ -77,7 +67,7 @@ static void if_usb_write_bulk_callback(struct urb *urb) * valid at firmware load time. */ if (priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct net_device *dev = priv->dev; priv->dnld_sent = DNLD_RES_RECEIVED; @@ -86,10 +76,11 @@ static void if_usb_write_bulk_callback(struct urb *urb) if (!adapter->cur_cmd) wake_up_interruptible(&priv->waitq); - if ((adapter->connect_status == LIBERTAS_CONNECTED)) { + if (adapter->connect_status == LBS_CONNECTED) netif_wake_queue(dev); + + if (priv->mesh_dev && (adapter->mesh_connect_status == LBS_CONNECTED)) netif_wake_queue(priv->mesh_dev); - } } } else { /* print the failure status number for debug */ @@ -136,7 +127,7 @@ static int if_usb_probe(struct usb_interface *intf, struct usb_device *udev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; - wlan_private *priv; + struct lbs_private *priv; struct usb_card_rec *cardp; int i; @@ -222,12 +213,12 @@ static int if_usb_probe(struct usb_interface *intf, goto err_prog_firmware; } - if (!(priv = libertas_add_card(cardp, &udev->dev))) + if (!(priv = lbs_add_card(cardp, &udev->dev))) goto err_prog_firmware; cardp->priv = priv; - if (libertas_add_mesh(priv, &udev->dev)) + if (lbs_add_mesh(priv, &udev->dev)) goto err_add_mesh; cardp->eth_dev = priv->dev; @@ -242,20 +233,18 @@ static int if_usb_probe(struct usb_interface *intf, msleep_interruptible(200); priv->adapter->fw_ready = 1; - if (libertas_start_card(priv)) + if (lbs_start_card(priv)) goto err_start_card; - list_add_tail(&cardp->list, &usb_devices); - usb_get_dev(udev); usb_set_intfdata(intf, cardp); return 0; err_start_card: - libertas_remove_mesh(priv); + lbs_remove_mesh(priv); err_add_mesh: - libertas_remove_card(priv); + lbs_remove_card(priv); err_prog_firmware: if_usb_reset_device(cardp); dealloc: @@ -273,24 +262,26 @@ error: static void if_usb_disconnect(struct usb_interface *intf) { struct usb_card_rec *cardp = usb_get_intfdata(intf); - wlan_private *priv = (wlan_private *) cardp->priv; + struct lbs_private *priv = (struct lbs_private *) cardp->priv; lbs_deb_enter(LBS_DEB_MAIN); /* Update Surprise removed to TRUE */ cardp->surprise_removed = 1; - list_del(&cardp->list); - if (priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; adapter->surpriseremoved = 1; - libertas_stop_card(priv); - libertas_remove_mesh(priv); - libertas_remove_card(priv); + lbs_stop_card(priv); + lbs_remove_mesh(priv); + lbs_remove_card(priv); } + /* this is (apparently?) necessary for future usage of the device */ + lbs_prepare_and_send_command(priv, CMD_802_11_RESET, CMD_ACT_HALT, + 0, 0, NULL); + /* Unlink and free urb */ if_usb_free(cardp); @@ -302,7 +293,7 @@ static void if_usb_disconnect(struct usb_interface *intf) /** * @brief This function download FW - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @return 0 */ static int if_prog_firmware(struct usb_card_rec *cardp) @@ -385,7 +376,7 @@ static int if_prog_firmware(struct usb_card_rec *cardp) static int if_usb_reset_device(struct usb_card_rec *cardp) { int ret; - wlan_private * priv = cardp->priv; + struct lbs_private *priv = cardp->priv; lbs_deb_enter(LBS_DEB_USB); @@ -395,7 +386,7 @@ static int if_usb_reset_device(struct usb_card_rec *cardp) ret = usb_reset_device(cardp->udev); if (!ret && priv) { msleep(10); - ret = libertas_reset_device(priv); + ret = lbs_reset_device(priv); msleep(10); } @@ -406,7 +397,7 @@ static int if_usb_reset_device(struct usb_card_rec *cardp) /** * @brief This function transfer the data to the device. - * @param priv pointer to wlan_private + * @param priv pointer to struct lbs_private * @param payload pointer to payload data * @param nb data length * @return 0 or -1 @@ -583,7 +574,7 @@ exit: static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, struct usb_card_rec *cardp, - wlan_private *priv) + struct lbs_private *priv) { if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN || recvlength < MRVDRV_MIN_PKT_LEN) { @@ -596,14 +587,14 @@ static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb, skb_reserve(skb, IPFIELD_ALIGN_OFFSET); skb_put(skb, recvlength); skb_pull(skb, MESSAGE_HEADER_LEN); - libertas_process_rxed_packet(priv, skb); + lbs_process_rxed_packet(priv, skb); priv->upld_len = (recvlength - MESSAGE_HEADER_LEN); } static inline void process_cmdrequest(int recvlength, u8 *recvbuff, struct sk_buff *skb, struct usb_card_rec *cardp, - wlan_private *priv) + struct lbs_private *priv) { u8 *cmdbuf; if (recvlength > MRVDRV_SIZE_OF_CMD_BUFFER) { @@ -631,7 +622,7 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff, priv->upld_len); kfree_skb(skb); - libertas_interrupt(priv->dev); + lbs_interrupt(priv->dev); spin_unlock(&priv->adapter->driver_lock); lbs_deb_usbd(&cardp->udev->dev, @@ -652,7 +643,7 @@ static void if_usb_receive(struct urb *urb) struct read_cb_info *rinfo = (struct read_cb_info *)urb->context; struct sk_buff *skb = rinfo->skb; struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp; - wlan_private * priv = cardp->priv; + struct lbs_private *priv = cardp->priv; int recvlength = urb->actual_length; u8 *recvbuff = NULL; @@ -695,14 +686,14 @@ static void if_usb_receive(struct urb *urb) lbs_deb_usbd(&cardp->udev->dev,"**EVENT** 0x%X\n", cardp->usb_event_cause); if (cardp->usb_event_cause & 0xffff0000) { - libertas_send_tx_feedback(priv); + lbs_send_tx_feedback(priv); spin_unlock(&priv->adapter->driver_lock); break; } cardp->usb_event_cause <<= 3; cardp->usb_int_cause |= MRVDRV_CARDEVENT; kfree_skb(skb); - libertas_interrupt(priv->dev); + lbs_interrupt(priv->dev); spin_unlock(&priv->adapter->driver_lock); goto rx_exit; default: @@ -720,13 +711,16 @@ rx_exit: /** * @brief This function downloads data to FW - * @param priv pointer to wlan_private structure + * @param priv pointer to struct lbs_private structure * @param type type of data * @param buf pointer to data buffer * @param len number of bytes * @return 0 or -1 */ -static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb) +static int if_usb_host_to_card(struct lbs_private *priv, + u8 type, + u8 *payload, + u16 nb) { struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; @@ -753,7 +747,7 @@ static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 n } /* called with adapter->driver_lock held */ -static int if_usb_get_int_status(wlan_private * priv, u8 * ireg) +static int if_usb_get_int_status(struct lbs_private *priv, u8 *ireg) { struct usb_card_rec *cardp = priv->card; @@ -765,7 +759,7 @@ static int if_usb_get_int_status(wlan_private * priv, u8 * ireg) return 0; } -static int if_usb_read_event_cause(wlan_private * priv) +static int if_usb_read_event_cause(struct lbs_private *priv) { struct usb_card_rec *cardp = priv->card; @@ -856,10 +850,10 @@ static int if_usb_prog_firmware(struct usb_card_rec *cardp) lbs_deb_enter(LBS_DEB_USB); - if ((ret = request_firmware(&cardp->fw, libertas_fw_name, + if ((ret = request_firmware(&cardp->fw, lbs_fw_name, &cardp->udev->dev)) < 0) { lbs_pr_err("request_firmware() failed with %#x\n", ret); - lbs_pr_err("firmware %s not found\n", libertas_fw_name); + lbs_pr_err("firmware %s not found\n", lbs_fw_name); goto done; } @@ -940,7 +934,7 @@ done: static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) { struct usb_card_rec *cardp = usb_get_intfdata(intf); - wlan_private *priv = cardp->priv; + struct lbs_private *priv = cardp->priv; lbs_deb_enter(LBS_DEB_USB); @@ -954,7 +948,7 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); mesh_access.data[0] = cpu_to_le32(1); - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_MESH_ACCESS, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -976,7 +970,7 @@ static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) static int if_usb_resume(struct usb_interface *intf) { struct usb_card_rec *cardp = usb_get_intfdata(intf); - wlan_private *priv = cardp->priv; + struct lbs_private *priv = cardp->priv; lbs_deb_enter(LBS_DEB_USB); @@ -994,7 +988,7 @@ static int if_usb_resume(struct usb_interface *intf) struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); mesh_access.data[0] = cpu_to_le32(0); - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_MESH_ACCESS, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -1009,46 +1003,30 @@ static int if_usb_resume(struct usb_interface *intf) #endif static struct usb_driver if_usb_driver = { - /* driver name */ - .name = usbdriver_name, - /* probe function name */ + .name = DRV_NAME, .probe = if_usb_probe, - /* disconnect function name */ .disconnect = if_usb_disconnect, - /* device signature table */ .id_table = if_usb_table, .suspend = if_usb_suspend, .resume = if_usb_resume, }; -static int if_usb_init_module(void) +static int __init if_usb_init_module(void) { int ret = 0; lbs_deb_enter(LBS_DEB_MAIN); - if (libertas_fw_name == NULL) { - libertas_fw_name = default_fw_name; - } - ret = usb_register(&if_usb_driver); lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } -static void if_usb_exit_module(void) +static void __exit if_usb_exit_module(void) { - struct usb_card_rec *cardp, *cardp_temp; - lbs_deb_enter(LBS_DEB_MAIN); - list_for_each_entry_safe(cardp, cardp_temp, &usb_devices, list) { - libertas_prepare_and_send_command(cardp->priv, CMD_802_11_RESET, - CMD_ACT_HALT, 0, 0, NULL); - } - - /* API unregisters the driver from USB subsystem */ usb_deregister(&if_usb_driver); lbs_deb_leave(LBS_DEB_MAIN); diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index e07a10e..f53ddb2 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h @@ -1,7 +1,5 @@ -#ifndef _LIBERTAS_IF_USB_H -#define _LIBERTAS_IF_USB_H - -#include +#ifndef _LBS_IF_USB_H +#define _LBS_IF_USB_H /** * This file contains definition for USB interface. @@ -44,7 +42,6 @@ struct read_cb_info { /** USB card description structure*/ struct usb_card_rec { - struct list_head list; struct net_device *eth_dev; struct usb_device *udev; struct urb *rx_urb, *tx_urb; diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c index dc24a05..1550e6a 100644 --- a/drivers/net/wireless/libertas/join.c +++ b/drivers/net/wireless/libertas/join.c @@ -30,16 +30,18 @@ * NOTE: Setting the MSB of the basic rates need to be taken * care, either before or after calling this function * - * @param adapter A pointer to wlan_adapter structure + * @param adapter A pointer to struct lbs_adapter structure * @param rate1 the buffer which keeps input and output * @param rate1_size the size of rate1 buffer; new size of buffer on return * * @return 0 or -1 */ -static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size) +static int get_common_rates(struct lbs_adapter *adapter, + u8 *rates, + u16 *rates_size) { - u8 *card_rates = libertas_bg_rates; - size_t num_card_rates = sizeof(libertas_bg_rates); + u8 *card_rates = lbs_bg_rates; + size_t num_card_rates = sizeof(lbs_bg_rates); int ret = 0, i, j; u8 tmp[30]; size_t tmp_size = 0; @@ -55,7 +57,7 @@ static int get_common_rates(wlan_adapter * adapter, u8 * rates, u16 *rates_size) lbs_deb_hex(LBS_DEB_JOIN, "AP rates ", rates, *rates_size); lbs_deb_hex(LBS_DEB_JOIN, "card rates ", card_rates, num_card_rates); lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size); - lbs_deb_join("Tx datarate is currently 0x%X\n", adapter->cur_rate); + lbs_deb_join("TX data rate 0x%02x\n", adapter->cur_rate); if (!adapter->auto_rate) { for (i = 0; i < tmp_size; i++) { @@ -85,7 +87,7 @@ done: * @param rates buffer of data rates * @param len size of buffer */ -static void libertas_set_basic_rate_flags(u8 * rates, size_t len) +static void lbs_set_basic_rate_flags(u8 *rates, size_t len) { int i; @@ -104,7 +106,7 @@ static void libertas_set_basic_rate_flags(u8 * rates, size_t len) * @param rates buffer of data rates * @param len size of buffer */ -void libertas_unset_basic_rate_flags(u8 * rates, size_t len) +void lbs_unset_basic_rate_flags(u8 *rates, size_t len) { int i; @@ -116,19 +118,19 @@ void libertas_unset_basic_rate_flags(u8 * rates, size_t len) /** * @brief Associate to a specific BSS discovered in a scan * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param pbssdesc Pointer to the BSS descriptor to associate with. * * @return 0-success, otherwise fail */ -int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req) +int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret; - lbs_deb_enter(LBS_DEB_JOIN); + lbs_deb_enter(LBS_DEB_ASSOC); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, 0, CMD_OPTION_WAITFORRSP, 0, assoc_req->bss.bssid); @@ -142,26 +144,27 @@ int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req) else adapter->preamble = CMD_TYPE_LONG_PREAMBLE; - libertas_set_radio_control(priv); + lbs_set_radio_control(priv); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); done: - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } /** * @brief Start an Adhoc Network * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param adhocssid The ssid of the Adhoc Network * @return 0--success, -1--fail */ -int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) +int lbs_start_adhoc_network(struct lbs_private *priv, + struct assoc_request *assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; adapter->adhoccreate = 1; @@ -174,12 +177,12 @@ int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * ass adapter->preamble = CMD_TYPE_LONG_PREAMBLE; } - libertas_set_radio_control(priv); + lbs_set_radio_control(priv); lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel); lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START, 0, CMD_OPTION_WAITFORRSP, 0, assoc_req); return ret; @@ -188,15 +191,16 @@ int libertas_start_adhoc_network(wlan_private * priv, struct assoc_request * ass /** * @brief Join an adhoc network found in a previous scan * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param pbssdesc Pointer to a BSS descriptor found in a previous scan * to attempt to join * * @return 0--success, -1--fail */ -int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * assoc_req) +int lbs_join_adhoc_network(struct lbs_private *priv, + struct assoc_request *assoc_req) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct bss_descriptor * bss = &assoc_req->bss; int ret = 0; @@ -211,11 +215,11 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso /* check if the requested SSID is already joined */ if ( adapter->curbssparams.ssid_len - && !libertas_ssid_cmp(adapter->curbssparams.ssid, + && !lbs_ssid_cmp(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len, bss->ssid, bss->ssid_len) && (adapter->mode == IW_MODE_ADHOC) - && (adapter->connect_status == LIBERTAS_CONNECTED)) { + && (adapter->connect_status == LBS_CONNECTED)) { union iwreq_data wrqu; lbs_deb_join("ADHOC_J_CMD: New ad-hoc SSID is the same as " @@ -243,14 +247,14 @@ int libertas_join_adhoc_network(wlan_private * priv, struct assoc_request * asso adapter->preamble = CMD_TYPE_SHORT_PREAMBLE; } - libertas_set_radio_control(priv); + lbs_set_radio_control(priv); lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel); lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band); adapter->adhoccreate = 0; - ret = libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_JOIN, 0, CMD_OPTION_WAITFORRSP, OID_802_11_SSID, assoc_req); @@ -258,38 +262,38 @@ out: return ret; } -int libertas_stop_adhoc_network(wlan_private * priv) +int lbs_stop_adhoc_network(struct lbs_private *priv) { - return libertas_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP, + return lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_STOP, 0, CMD_OPTION_WAITFORRSP, 0, NULL); } /** * @brief Send Deauthentication Request * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return 0--success, -1--fail */ -int libertas_send_deauthentication(wlan_private * priv) +int lbs_send_deauthentication(struct lbs_private *priv) { - return libertas_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE, + return lbs_prepare_and_send_command(priv, CMD_802_11_DEAUTHENTICATE, 0, CMD_OPTION_WAITFORRSP, 0, NULL); } /** * @brief This function prepares command of authenticate. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param cmd A pointer to cmd_ds_command structure * @param pdata_buf Void cast of pointer to a BSSID to authenticate with * * @return 0 or -1 */ -int libertas_cmd_80211_authenticate(wlan_private * priv, +int lbs_cmd_80211_authenticate(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth; int ret = -1; u8 *bssid = pdata_buf; @@ -320,7 +324,7 @@ int libertas_cmd_80211_authenticate(wlan_private * priv, memcpy(pauthenticate->macaddr, bssid, ETH_ALEN); - lbs_deb_join("AUTH_CMD: BSSID is : %s auth=0x%X\n", + lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", print_mac(mac, bssid), pauthenticate->authtype); ret = 0; @@ -329,10 +333,10 @@ out: return ret; } -int libertas_cmd_80211_deauthenticate(wlan_private * priv, +int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, struct cmd_ds_command *cmd) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_deauthenticate *dauth = &cmd->params.deauth; lbs_deb_enter(LBS_DEB_JOIN); @@ -352,10 +356,10 @@ int libertas_cmd_80211_deauthenticate(wlan_private * priv, return 0; } -int libertas_cmd_80211_associate(wlan_private * priv, +int lbs_cmd_80211_associate(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_associate *passo = &cmd->params.associate; int ret = 0; struct assoc_request * assoc_req = pdata_buf; @@ -368,7 +372,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, struct mrvlietypes_ratesparamset *rates; struct mrvlietypes_rsnparamset *rsn; - lbs_deb_enter(LBS_DEB_JOIN); + lbs_deb_enter(LBS_DEB_ASSOC); pos = (u8 *) passo; @@ -422,7 +426,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, } pos += sizeof(rates->header) + tmplen; rates->header.len = cpu_to_le16(tmplen); - lbs_deb_join("ASSOC_CMD: num rates = %u\n", tmplen); + lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen); /* Copy the infra. association rates into Current BSS state structure */ memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates)); @@ -431,7 +435,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, /* Set MSB on basic rates as the firmware requires, but _after_ * copying to current bss rates. */ - libertas_set_basic_rate_flags(rates->rates, tmplen); + lbs_set_basic_rate_flags(rates->rates, tmplen); if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { rsn = (struct mrvlietypes_rsnparamset *) pos; @@ -448,7 +452,7 @@ int libertas_cmd_80211_associate(wlan_private * priv, /* update curbssparams */ adapter->curbssparams.channel = bss->phyparamset.dsparamset.currentchan; - if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { + if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } @@ -460,18 +464,17 @@ int libertas_cmd_80211_associate(wlan_private * priv, if (bss->mode == IW_MODE_INFRA) tmpcap |= WLAN_CAPABILITY_ESS; passo->capability = cpu_to_le16(tmpcap); - lbs_deb_join("ASSOC_CMD: capability=%4X CAPINFO_MASK=%4X\n", - tmpcap, CAPINFO_MASK); + lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap); done: - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } -int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_start *adhs = &cmd->params.ads; int ret = 0; int cmdappendsize = 0; @@ -510,7 +513,9 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, /* set the BSS type */ adhs->bsstype = CMD_BSS_TYPE_IBSS; adapter->mode = IW_MODE_ADHOC; - adhs->beaconperiod = cpu_to_le16(MRVDRV_BEACON_INTERVAL); + if (adapter->beacon_period == 0) + adapter->beacon_period = MRVDRV_BEACON_INTERVAL; + adhs->beaconperiod = cpu_to_le16(adapter->beacon_period); /* set Physical param set */ #define DS_PARA_IE_ID 3 @@ -548,8 +553,8 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, adhs->probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); memset(adhs->rates, 0, sizeof(adhs->rates)); - ratesize = min(sizeof(adhs->rates), sizeof(libertas_bg_rates)); - memcpy(adhs->rates, libertas_bg_rates, ratesize); + ratesize = min(sizeof(adhs->rates), sizeof(lbs_bg_rates)); + memcpy(adhs->rates, lbs_bg_rates, ratesize); /* Copy the ad-hoc creating rates into Current BSS state structure */ memset(&adapter->curbssparams.rates, 0, sizeof(adapter->curbssparams.rates)); @@ -558,14 +563,14 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, /* Set MSB on basic rates as the firmware requires, but _after_ * copying to current bss rates. */ - libertas_set_basic_rate_flags(adhs->rates, ratesize); + lbs_set_basic_rate_flags(adhs->rates, ratesize); lbs_deb_join("ADHOC_S_CMD: rates=%02x %02x %02x %02x \n", adhs->rates[0], adhs->rates[1], adhs->rates[2], adhs->rates[3]); lbs_deb_join("ADHOC_S_CMD: AD HOC Start command is ready\n"); - if (libertas_create_dnld_countryinfo_11d(priv)) { + if (lbs_create_dnld_countryinfo_11d(priv)) { lbs_deb_join("ADHOC_S_CMD: dnld_countryinfo_11d failed\n"); ret = -1; goto done; @@ -580,7 +585,7 @@ done: return ret; } -int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv, struct cmd_ds_command *cmd) { cmd->command = cpu_to_le16(CMD_802_11_AD_HOC_STOP); @@ -589,10 +594,10 @@ int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, return 0; } -int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_ad_hoc_join *join_cmd = &cmd->params.adj; struct assoc_request * assoc_req = pdata_buf; struct bss_descriptor *bss = &assoc_req->bss; @@ -652,7 +657,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, /* Set MSB on basic rates as the firmware requires, but _after_ * copying to current bss rates. */ - libertas_set_basic_rate_flags(join_cmd->bss.rates, ratesize); + lbs_set_basic_rate_flags(join_cmd->bss.rates, ratesize); join_cmd->bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow); @@ -663,12 +668,12 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, join_cmd->bss.capability = cpu_to_le16(tmp); } - if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) { + if (adapter->psmode == LBS802_11POWERMODEMAX_PSP) { /* wake up first */ __le32 Localpsmode; - Localpsmode = cpu_to_le32(WLAN802_11POWERMODECAM); - ret = libertas_prepare_and_send_command(priv, + Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM); + ret = lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE, CMD_ACT_SET, 0, 0, &Localpsmode); @@ -679,7 +684,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, } } - if (libertas_parse_dnld_countryinfo_11d(priv, bss)) { + if (lbs_parse_dnld_countryinfo_11d(priv, bss)) { ret = -1; goto done; } @@ -692,20 +697,20 @@ done: return ret; } -int libertas_ret_80211_associate(wlan_private * priv, +int lbs_ret_80211_associate(struct lbs_private *priv, struct cmd_ds_command *resp) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; union iwreq_data wrqu; struct ieeetypes_assocrsp *passocrsp; struct bss_descriptor * bss; u16 status_code; - lbs_deb_enter(LBS_DEB_JOIN); + lbs_deb_enter(LBS_DEB_ASSOC); if (!adapter->in_progress_assoc_req) { - lbs_deb_join("ASSOC_RESP: no in-progress association request\n"); + lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n"); ret = -1; goto done; } @@ -734,55 +739,47 @@ int libertas_ret_80211_associate(wlan_private * priv, status_code = le16_to_cpu(passocrsp->statuscode); switch (status_code) { case 0x00: - lbs_deb_join("ASSOC_RESP: Association succeeded\n"); break; case 0x01: - lbs_deb_join("ASSOC_RESP: Association failed; invalid " - "parameters (status code %d)\n", status_code); + lbs_deb_assoc("ASSOC_RESP: invalid parameters\n"); break; case 0x02: - lbs_deb_join("ASSOC_RESP: Association failed; internal timer " - "expired while waiting for the AP (status code %d)" - "\n", status_code); + lbs_deb_assoc("ASSOC_RESP: internal timer " + "expired while waiting for the AP\n"); break; case 0x03: - lbs_deb_join("ASSOC_RESP: Association failed; association " - "was refused by the AP (status code %d)\n", - status_code); + lbs_deb_assoc("ASSOC_RESP: association " + "refused by AP\n"); break; case 0x04: - lbs_deb_join("ASSOC_RESP: Association failed; authentication " - "was refused by the AP (status code %d)\n", - status_code); + lbs_deb_assoc("ASSOC_RESP: authentication " + "refused by AP\n"); break; default: - lbs_deb_join("ASSOC_RESP: Association failed; reason unknown " - "(status code %d)\n", status_code); + lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x " + " unknown\n", status_code); break; } if (status_code) { - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); ret = -1; goto done; } - lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_RESP", (void *)&resp->params, + lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params, le16_to_cpu(resp->size) - S_DS_GEN); /* Send a Media Connected event, according to the Spec */ - adapter->connect_status = LIBERTAS_CONNECTED; - - lbs_deb_join("ASSOC_RESP: assocated to '%s'\n", - escape_essid(bss->ssid, bss->ssid_len)); + adapter->connect_status = LBS_CONNECTED; /* Update current SSID and BSSID */ memcpy(&adapter->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE); adapter->curbssparams.ssid_len = bss->ssid_len; memcpy(adapter->curbssparams.bssid, bss->bssid, ETH_ALEN); - lbs_deb_join("ASSOC_RESP: currentpacketfilter is %x\n", - adapter->currentpacketfilter); + lbs_deb_assoc("ASSOC_RESP: currentpacketfilter is 0x%x\n", + adapter->currentpacketfilter); adapter->SNR[TYPE_RXPD][TYPE_AVG] = 0; adapter->NF[TYPE_RXPD][TYPE_AVG] = 0; @@ -795,35 +792,31 @@ int libertas_ret_80211_associate(wlan_private * priv, netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - if (priv->mesh_dev) { - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); - } memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); done: - lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); return ret; } -int libertas_ret_80211_disassociate(wlan_private * priv, +int lbs_ret_80211_disassociate(struct lbs_private *priv, struct cmd_ds_command *resp) { lbs_deb_enter(LBS_DEB_JOIN); - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); lbs_deb_leave(LBS_DEB_JOIN); return 0; } -int libertas_ret_80211_ad_hoc_start(wlan_private * priv, +int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *resp) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; u16 command = le16_to_cpu(resp->command); u16 result = le16_to_cpu(resp->result); @@ -852,8 +845,8 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, */ if (result) { lbs_deb_join("ADHOC_RESP: failed\n"); - if (adapter->connect_status == LIBERTAS_CONNECTED) { - libertas_mac_event_disconnected(priv); + if (adapter->connect_status == LBS_CONNECTED) { + lbs_mac_event_disconnected(priv); } ret = -1; goto done; @@ -867,7 +860,7 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, escape_essid(bss->ssid, bss->ssid_len)); /* Send a Media Connected event, according to the Spec */ - adapter->connect_status = LIBERTAS_CONNECTED; + adapter->connect_status = LBS_CONNECTED; if (command == CMD_RET(CMD_802_11_AD_HOC_START)) { /* Update the created network descriptor with the new BSSID */ @@ -884,11 +877,6 @@ int libertas_ret_80211_ad_hoc_start(wlan_private * priv, netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - if (priv->mesh_dev) { - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); - } - memset(&wrqu, 0, sizeof(wrqu)); memcpy(wrqu.ap_addr.sa_data, adapter->curbssparams.bssid, ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -904,12 +892,12 @@ done: return ret; } -int libertas_ret_80211_ad_hoc_stop(wlan_private * priv, +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv, struct cmd_ds_command *resp) { lbs_deb_enter(LBS_DEB_JOIN); - libertas_mac_event_disconnected(priv); + lbs_mac_event_disconnected(priv); lbs_deb_leave(LBS_DEB_JOIN); return 0; diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h index 894a072..c617d07 100644 --- a/drivers/net/wireless/libertas/join.h +++ b/drivers/net/wireless/libertas/join.h @@ -2,52 +2,52 @@ * Interface for the wlan infrastructure and adhoc join routines * * Driver interface functions and type declarations for the join module - * implemented in wlan_join.c. Process all start/join requests for + * implemented in join.c. Process all start/join requests for * both adhoc and infrastructure networks */ -#ifndef _WLAN_JOIN_H -#define _WLAN_JOIN_H +#ifndef _LBS_JOIN_H +#define _LBS_JOIN_H #include "defs.h" #include "dev.h" struct cmd_ds_command; -int libertas_cmd_80211_authenticate(wlan_private * priv, +int lbs_cmd_80211_authenticate(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int libertas_cmd_80211_ad_hoc_join(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_join(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int libertas_cmd_80211_ad_hoc_stop(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_stop(struct lbs_private *priv, struct cmd_ds_command *cmd); -int libertas_cmd_80211_ad_hoc_start(wlan_private * priv, +int lbs_cmd_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int libertas_cmd_80211_deauthenticate(wlan_private * priv, +int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, struct cmd_ds_command *cmd); -int libertas_cmd_80211_associate(wlan_private * priv, +int lbs_cmd_80211_associate(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int libertas_ret_80211_ad_hoc_start(wlan_private * priv, +int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, struct cmd_ds_command *resp); -int libertas_ret_80211_ad_hoc_stop(wlan_private * priv, +int lbs_ret_80211_ad_hoc_stop(struct lbs_private *priv, struct cmd_ds_command *resp); -int libertas_ret_80211_disassociate(wlan_private * priv, +int lbs_ret_80211_disassociate(struct lbs_private *priv, struct cmd_ds_command *resp); -int libertas_ret_80211_associate(wlan_private * priv, +int lbs_ret_80211_associate(struct lbs_private *priv, struct cmd_ds_command *resp); -int libertas_start_adhoc_network(wlan_private * priv, +int lbs_start_adhoc_network(struct lbs_private *priv, struct assoc_request * assoc_req); -int libertas_join_adhoc_network(wlan_private * priv, +int lbs_join_adhoc_network(struct lbs_private *priv, struct assoc_request * assoc_req); -int libertas_stop_adhoc_network(wlan_private * priv); +int lbs_stop_adhoc_network(struct lbs_private *priv); -int libertas_send_deauthentication(wlan_private * priv); +int lbs_send_deauthentication(struct lbs_private *priv); -int wlan_associate(wlan_private * priv, struct assoc_request * assoc_req); +int lbs_associate(struct lbs_private *priv, struct assoc_request *assoc_req); -void libertas_unset_basic_rate_flags(u8 * rates, size_t len); +void lbs_unset_basic_rate_flags(u8 *rates, size_t len); #endif diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 1823b48..67b6d79 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -24,7 +24,7 @@ #include "join.h" #define DRIVER_RELEASE_VERSION "323.p0" -const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION +const char lbs_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION #ifdef DEBUG "-dbg" #endif @@ -32,80 +32,80 @@ const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION /* Module parameters */ -unsigned int libertas_debug = 0; -module_param(libertas_debug, int, 0644); -EXPORT_SYMBOL_GPL(libertas_debug); +unsigned int lbs_debug; +EXPORT_SYMBOL_GPL(lbs_debug); +module_param_named(libertas_debug, lbs_debug, int, 0644); -#define WLAN_TX_PWR_DEFAULT 20 /*100mW */ -#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW */ -#define WLAN_TX_PWR_JP_DEFAULT 16 /*50mW */ -#define WLAN_TX_PWR_FR_DEFAULT 20 /*100mW */ -#define WLAN_TX_PWR_EMEA_DEFAULT 20 /*100mW */ +#define LBS_TX_PWR_DEFAULT 20 /*100mW */ +#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */ +#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */ +#define LBS_TX_PWR_FR_DEFAULT 20 /*100mW */ +#define LBS_TX_PWR_EMEA_DEFAULT 20 /*100mW */ /* Format { channel, frequency (MHz), maxtxpower } */ /* band: 'B/G', region: USA FCC/Canada IC */ static struct chan_freq_power channel_freq_power_US_BG[] = { - {1, 2412, WLAN_TX_PWR_US_DEFAULT}, - {2, 2417, WLAN_TX_PWR_US_DEFAULT}, - {3, 2422, WLAN_TX_PWR_US_DEFAULT}, - {4, 2427, WLAN_TX_PWR_US_DEFAULT}, - {5, 2432, WLAN_TX_PWR_US_DEFAULT}, - {6, 2437, WLAN_TX_PWR_US_DEFAULT}, - {7, 2442, WLAN_TX_PWR_US_DEFAULT}, - {8, 2447, WLAN_TX_PWR_US_DEFAULT}, - {9, 2452, WLAN_TX_PWR_US_DEFAULT}, - {10, 2457, WLAN_TX_PWR_US_DEFAULT}, - {11, 2462, WLAN_TX_PWR_US_DEFAULT} + {1, 2412, LBS_TX_PWR_US_DEFAULT}, + {2, 2417, LBS_TX_PWR_US_DEFAULT}, + {3, 2422, LBS_TX_PWR_US_DEFAULT}, + {4, 2427, LBS_TX_PWR_US_DEFAULT}, + {5, 2432, LBS_TX_PWR_US_DEFAULT}, + {6, 2437, LBS_TX_PWR_US_DEFAULT}, + {7, 2442, LBS_TX_PWR_US_DEFAULT}, + {8, 2447, LBS_TX_PWR_US_DEFAULT}, + {9, 2452, LBS_TX_PWR_US_DEFAULT}, + {10, 2457, LBS_TX_PWR_US_DEFAULT}, + {11, 2462, LBS_TX_PWR_US_DEFAULT} }; /* band: 'B/G', region: Europe ETSI */ static struct chan_freq_power channel_freq_power_EU_BG[] = { - {1, 2412, WLAN_TX_PWR_EMEA_DEFAULT}, - {2, 2417, WLAN_TX_PWR_EMEA_DEFAULT}, - {3, 2422, WLAN_TX_PWR_EMEA_DEFAULT}, - {4, 2427, WLAN_TX_PWR_EMEA_DEFAULT}, - {5, 2432, WLAN_TX_PWR_EMEA_DEFAULT}, - {6, 2437, WLAN_TX_PWR_EMEA_DEFAULT}, - {7, 2442, WLAN_TX_PWR_EMEA_DEFAULT}, - {8, 2447, WLAN_TX_PWR_EMEA_DEFAULT}, - {9, 2452, WLAN_TX_PWR_EMEA_DEFAULT}, - {10, 2457, WLAN_TX_PWR_EMEA_DEFAULT}, - {11, 2462, WLAN_TX_PWR_EMEA_DEFAULT}, - {12, 2467, WLAN_TX_PWR_EMEA_DEFAULT}, - {13, 2472, WLAN_TX_PWR_EMEA_DEFAULT} + {1, 2412, LBS_TX_PWR_EMEA_DEFAULT}, + {2, 2417, LBS_TX_PWR_EMEA_DEFAULT}, + {3, 2422, LBS_TX_PWR_EMEA_DEFAULT}, + {4, 2427, LBS_TX_PWR_EMEA_DEFAULT}, + {5, 2432, LBS_TX_PWR_EMEA_DEFAULT}, + {6, 2437, LBS_TX_PWR_EMEA_DEFAULT}, + {7, 2442, LBS_TX_PWR_EMEA_DEFAULT}, + {8, 2447, LBS_TX_PWR_EMEA_DEFAULT}, + {9, 2452, LBS_TX_PWR_EMEA_DEFAULT}, + {10, 2457, LBS_TX_PWR_EMEA_DEFAULT}, + {11, 2462, LBS_TX_PWR_EMEA_DEFAULT}, + {12, 2467, LBS_TX_PWR_EMEA_DEFAULT}, + {13, 2472, LBS_TX_PWR_EMEA_DEFAULT} }; /* band: 'B/G', region: Spain */ static struct chan_freq_power channel_freq_power_SPN_BG[] = { - {10, 2457, WLAN_TX_PWR_DEFAULT}, - {11, 2462, WLAN_TX_PWR_DEFAULT} + {10, 2457, LBS_TX_PWR_DEFAULT}, + {11, 2462, LBS_TX_PWR_DEFAULT} }; /* band: 'B/G', region: France */ static struct chan_freq_power channel_freq_power_FR_BG[] = { - {10, 2457, WLAN_TX_PWR_FR_DEFAULT}, - {11, 2462, WLAN_TX_PWR_FR_DEFAULT}, - {12, 2467, WLAN_TX_PWR_FR_DEFAULT}, - {13, 2472, WLAN_TX_PWR_FR_DEFAULT} + {10, 2457, LBS_TX_PWR_FR_DEFAULT}, + {11, 2462, LBS_TX_PWR_FR_DEFAULT}, + {12, 2467, LBS_TX_PWR_FR_DEFAULT}, + {13, 2472, LBS_TX_PWR_FR_DEFAULT} }; /* band: 'B/G', region: Japan */ static struct chan_freq_power channel_freq_power_JPN_BG[] = { - {1, 2412, WLAN_TX_PWR_JP_DEFAULT}, - {2, 2417, WLAN_TX_PWR_JP_DEFAULT}, - {3, 2422, WLAN_TX_PWR_JP_DEFAULT}, - {4, 2427, WLAN_TX_PWR_JP_DEFAULT}, - {5, 2432, WLAN_TX_PWR_JP_DEFAULT}, - {6, 2437, WLAN_TX_PWR_JP_DEFAULT}, - {7, 2442, WLAN_TX_PWR_JP_DEFAULT}, - {8, 2447, WLAN_TX_PWR_JP_DEFAULT}, - {9, 2452, WLAN_TX_PWR_JP_DEFAULT}, - {10, 2457, WLAN_TX_PWR_JP_DEFAULT}, - {11, 2462, WLAN_TX_PWR_JP_DEFAULT}, - {12, 2467, WLAN_TX_PWR_JP_DEFAULT}, - {13, 2472, WLAN_TX_PWR_JP_DEFAULT}, - {14, 2484, WLAN_TX_PWR_JP_DEFAULT} + {1, 2412, LBS_TX_PWR_JP_DEFAULT}, + {2, 2417, LBS_TX_PWR_JP_DEFAULT}, + {3, 2422, LBS_TX_PWR_JP_DEFAULT}, + {4, 2427, LBS_TX_PWR_JP_DEFAULT}, + {5, 2432, LBS_TX_PWR_JP_DEFAULT}, + {6, 2437, LBS_TX_PWR_JP_DEFAULT}, + {7, 2442, LBS_TX_PWR_JP_DEFAULT}, + {8, 2447, LBS_TX_PWR_JP_DEFAULT}, + {9, 2452, LBS_TX_PWR_JP_DEFAULT}, + {10, 2457, LBS_TX_PWR_JP_DEFAULT}, + {11, 2462, LBS_TX_PWR_JP_DEFAULT}, + {12, 2467, LBS_TX_PWR_JP_DEFAULT}, + {13, 2472, LBS_TX_PWR_JP_DEFAULT}, + {14, 2484, LBS_TX_PWR_JP_DEFAULT} }; /** @@ -153,13 +153,13 @@ static struct region_cfp_table region_cfp_table[] = { /** * the table to keep region code */ -u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = +u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] = { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; /** * 802.11b/g supported bitrates (in 500Kb/s units) */ -u8 libertas_bg_rates[MAX_RATES] = +u8 lbs_bg_rates[MAX_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0x00, 0x00 }; @@ -179,7 +179,7 @@ static u8 fw_data_rates[MAX_RATES] = * @param idx The index of data rate * @return data rate or 0 */ -u32 libertas_fw_index_to_data_rate(u8 idx) +u32 lbs_fw_index_to_data_rate(u8 idx) { if (idx >= sizeof(fw_data_rates)) idx = 0; @@ -192,7 +192,7 @@ u32 libertas_fw_index_to_data_rate(u8 idx) * @param rate data rate * @return index or 0 */ -u8 libertas_data_rate_to_fw_index(u32 rate) +u8 lbs_data_rate_to_fw_index(u32 rate) { u8 i; @@ -213,13 +213,13 @@ u8 libertas_data_rate_to_fw_index(u32 rate) /** * @brief Get function for sysfs attribute anycast_mask */ -static ssize_t libertas_anycast_get(struct device * dev, +static ssize_t lbs_anycast_get(struct device *dev, struct device_attribute *attr, char * buf) { struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); - libertas_prepare_and_send_command(to_net_dev(dev)->priv, + lbs_prepare_and_send_command(to_net_dev(dev)->priv, CMD_MESH_ACCESS, CMD_ACT_MESH_GET_ANYCAST, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -230,7 +230,7 @@ static ssize_t libertas_anycast_get(struct device * dev, /** * @brief Set function for sysfs attribute anycast_mask */ -static ssize_t libertas_anycast_set(struct device * dev, +static ssize_t lbs_anycast_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { struct cmd_ds_mesh_access mesh_access; @@ -240,86 +240,88 @@ static ssize_t libertas_anycast_set(struct device * dev, sscanf(buf, "%x", &datum); mesh_access.data[0] = cpu_to_le32(datum); - libertas_prepare_and_send_command((to_net_dev(dev))->priv, + lbs_prepare_and_send_command((to_net_dev(dev))->priv, CMD_MESH_ACCESS, CMD_ACT_MESH_SET_ANYCAST, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); return strlen(buf); } -int libertas_add_rtap(wlan_private *priv); -void libertas_remove_rtap(wlan_private *priv); +int lbs_add_rtap(struct lbs_private *priv); +void lbs_remove_rtap(struct lbs_private *priv); /** * Get function for sysfs attribute rtap */ -static ssize_t libertas_rtap_get(struct device * dev, +static ssize_t lbs_rtap_get(struct device *dev, struct device_attribute *attr, char * buf) { - wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *) + (to_net_dev(dev))->priv; + struct lbs_adapter *adapter = priv->adapter; return snprintf(buf, 5, "0x%X\n", adapter->monitormode); } /** * Set function for sysfs attribute rtap */ -static ssize_t libertas_rtap_set(struct device * dev, +static ssize_t lbs_rtap_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { int monitor_mode; - wlan_private *priv = (wlan_private *) (to_net_dev(dev))->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *) + (to_net_dev(dev))->priv; + struct lbs_adapter *adapter = priv->adapter; sscanf(buf, "%x", &monitor_mode); - if (monitor_mode != WLAN_MONITOR_OFF) { + if (monitor_mode != LBS_MONITOR_OFF) { if(adapter->monitormode == monitor_mode) return strlen(buf); - if (adapter->monitormode == WLAN_MONITOR_OFF) { + if (adapter->monitormode == LBS_MONITOR_OFF) { if (adapter->mode == IW_MODE_INFRA) - libertas_send_deauthentication(priv); + lbs_send_deauthentication(priv); else if (adapter->mode == IW_MODE_ADHOC) - libertas_stop_adhoc_network(priv); - libertas_add_rtap(priv); + lbs_stop_adhoc_network(priv); + lbs_add_rtap(priv); } adapter->monitormode = monitor_mode; } else { - if(adapter->monitormode == WLAN_MONITOR_OFF) + if (adapter->monitormode == LBS_MONITOR_OFF) return strlen(buf); - adapter->monitormode = WLAN_MONITOR_OFF; - libertas_remove_rtap(priv); + adapter->monitormode = LBS_MONITOR_OFF; + lbs_remove_rtap(priv); netif_wake_queue(priv->dev); netif_wake_queue(priv->mesh_dev); } - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_802_11_MONITOR_MODE, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, &adapter->monitormode); return strlen(buf); } /** - * libertas_rtap attribute to be exported per mshX interface + * lbs_rtap attribute to be exported per mshX interface * through sysfs (/sys/class/net/mshX/libertas-rtap) */ -static DEVICE_ATTR(libertas_rtap, 0644, libertas_rtap_get, - libertas_rtap_set ); +static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, + lbs_rtap_set ); /** * anycast_mask attribute to be exported per mshX interface * through sysfs (/sys/class/net/mshX/anycast_mask) */ -static DEVICE_ATTR(anycast_mask, 0644, libertas_anycast_get, libertas_anycast_set); +static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set); -static ssize_t libertas_autostart_enabled_get(struct device * dev, +static ssize_t lbs_autostart_enabled_get(struct device *dev, struct device_attribute *attr, char * buf) { struct cmd_ds_mesh_access mesh_access; memset(&mesh_access, 0, sizeof(mesh_access)); - libertas_prepare_and_send_command(to_net_dev(dev)->priv, + lbs_prepare_and_send_command(to_net_dev(dev)->priv, CMD_MESH_ACCESS, CMD_ACT_MESH_GET_AUTOSTART_ENABLED, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -327,19 +329,19 @@ static ssize_t libertas_autostart_enabled_get(struct device * dev, return sprintf(buf, "%d\n", le32_to_cpu(mesh_access.data[0])); } -static ssize_t libertas_autostart_enabled_set(struct device * dev, +static ssize_t lbs_autostart_enabled_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { struct cmd_ds_mesh_access mesh_access; uint32_t datum; - wlan_private * priv = (to_net_dev(dev))->priv; + struct lbs_private *priv = (to_net_dev(dev))->priv; int ret; memset(&mesh_access, 0, sizeof(mesh_access)); sscanf(buf, "%d", &datum); mesh_access.data[0] = cpu_to_le32(datum); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_MESH_ACCESS, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -350,16 +352,16 @@ static ssize_t libertas_autostart_enabled_set(struct device * dev, } static DEVICE_ATTR(autostart_enabled, 0644, - libertas_autostart_enabled_get, libertas_autostart_enabled_set); + lbs_autostart_enabled_get, lbs_autostart_enabled_set); -static struct attribute *libertas_mesh_sysfs_entries[] = { +static struct attribute *lbs_mesh_sysfs_entries[] = { &dev_attr_anycast_mask.attr, &dev_attr_autostart_enabled.attr, NULL, }; -static struct attribute_group libertas_mesh_attr_group = { - .attrs = libertas_mesh_sysfs_entries, +static struct attribute_group lbs_mesh_attr_group = { + .attrs = lbs_mesh_sysfs_entries, }; /** @@ -375,8 +377,8 @@ static struct attribute_group libertas_mesh_attr_group = { */ static int pre_open_check(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *) dev->priv; + struct lbs_adapter *adapter = priv->adapter; int i = 0; while (!adapter->fw_ready && i < 20) { @@ -397,22 +399,24 @@ static int pre_open_check(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int libertas_dev_open(struct net_device *dev) +static int lbs_dev_open(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *) dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_NET); priv->open = 1; - if (adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->connect_status == LBS_CONNECTED) netif_carrier_on(priv->dev); - if (priv->mesh_dev) - netif_carrier_on(priv->mesh_dev); - } else { + else netif_carrier_off(priv->dev); - if (priv->mesh_dev) + + if (priv->mesh_dev) { + if (adapter->mesh_connect_status == LBS_CONNECTED) + netif_carrier_on(priv->mesh_dev); + else netif_carrier_off(priv->mesh_dev); } @@ -425,16 +429,21 @@ static int libertas_dev_open(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int libertas_mesh_open(struct net_device *dev) +static int lbs_mesh_open(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv ; + struct lbs_private *priv = (struct lbs_private *) dev->priv ; if (pre_open_check(dev) == -1) return -1; priv->mesh_open = 1 ; netif_wake_queue(priv->mesh_dev); + + priv->adapter->mesh_connect_status = LBS_CONNECTED; + + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); if (priv->infra_open == 0) - return libertas_dev_open(priv->dev) ; + return lbs_dev_open(priv->dev) ; return 0; } @@ -444,22 +453,22 @@ static int libertas_mesh_open(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int libertas_open(struct net_device *dev) +static int lbs_open(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv ; + struct lbs_private *priv = (struct lbs_private *) dev->priv ; if(pre_open_check(dev) == -1) return -1; priv->infra_open = 1 ; netif_wake_queue(priv->dev); if (priv->open == 0) - return libertas_dev_open(priv->dev) ; + return lbs_dev_open(priv->dev) ; return 0; } -static int libertas_dev_close(struct net_device *dev) +static int lbs_dev_close(struct net_device *dev) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; lbs_deb_enter(LBS_DEB_NET); @@ -476,14 +485,14 @@ static int libertas_dev_close(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int libertas_mesh_close(struct net_device *dev) +static int lbs_mesh_close(struct net_device *dev) { - wlan_private *priv = (wlan_private *) (dev->priv); + struct lbs_private *priv = (struct lbs_private *) (dev->priv); priv->mesh_open = 0; netif_stop_queue(priv->mesh_dev); if (priv->infra_open == 0) - return libertas_dev_close(dev); + return lbs_dev_close(dev); else return 0; } @@ -494,25 +503,25 @@ static int libertas_mesh_close(struct net_device *dev) * @param dev A pointer to net_device structure * @return 0 */ -static int libertas_close(struct net_device *dev) +static int lbs_close(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv; + struct lbs_private *priv = (struct lbs_private *) dev->priv; netif_stop_queue(dev); priv->infra_open = 0; if (priv->mesh_open == 0) - return libertas_dev_close(dev); + return lbs_dev_close(dev); else return 0; } -static int libertas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { int ret = 0; - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; - lbs_deb_enter(LBS_DEB_NET); + lbs_deb_enter(LBS_DEB_TX); if (priv->dnld_sent || priv->adapter->TxLockFlag) { priv->stats.tx_dropped++; @@ -523,62 +532,62 @@ static int libertas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if (priv->mesh_dev) netif_stop_queue(priv->mesh_dev); - if (libertas_process_tx(priv, skb) == 0) + if (lbs_process_tx(priv, skb) == 0) dev->trans_start = jiffies; done: - lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); return ret; } /** - * @brief Mark mesh packets and handover them to libertas_hard_start_xmit + * @brief Mark mesh packets and handover them to lbs_hard_start_xmit * */ -static int libertas_mesh_pre_start_xmit(struct sk_buff *skb, +static int lbs_mesh_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; int ret; lbs_deb_enter(LBS_DEB_MESH); - if(priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode != LBS_MONITOR_OFF) { netif_stop_queue(dev); return -EOPNOTSUPP; } SET_MESH_FRAME(skb); - ret = libertas_hard_start_xmit(skb, priv->dev); + ret = lbs_hard_start_xmit(skb, priv->mesh_dev); lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); return ret; } /** - * @brief Mark non-mesh packets and handover them to libertas_hard_start_xmit + * @brief Mark non-mesh packets and handover them to lbs_hard_start_xmit * */ -static int libertas_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int lbs_pre_start_xmit(struct sk_buff *skb, struct net_device *dev) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; int ret; - lbs_deb_enter(LBS_DEB_NET); + lbs_deb_enter(LBS_DEB_TX); - if(priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode != LBS_MONITOR_OFF) { netif_stop_queue(dev); return -EOPNOTSUPP; } UNSET_MESH_FRAME(skb); - ret = libertas_hard_start_xmit(skb, dev); - lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); + ret = lbs_hard_start_xmit(skb, dev); + lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); return ret; } -static void libertas_tx_timeout(struct net_device *dev) +static void lbs_tx_timeout(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv; + struct lbs_private *priv = (struct lbs_private *) dev->priv; lbs_deb_enter(LBS_DEB_TX); @@ -588,16 +597,19 @@ static void libertas_tx_timeout(struct net_device *dev) dev->trans_start = jiffies; if (priv->adapter->currenttxskb) { - if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode != LBS_MONITOR_OFF) { /* If we are here, we have not received feedback from the previous packet. Assume TX_FAIL and move on. */ priv->adapter->eventcause = 0x01000000; - libertas_send_tx_feedback(priv); + lbs_send_tx_feedback(priv); } else wake_up_interruptible(&priv->waitq); - } else if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { - netif_wake_queue(priv->dev); - if (priv->mesh_dev) + } else if (dev == priv->dev) { + if (priv->adapter->connect_status == LBS_CONNECTED) + netif_wake_queue(priv->dev); + + } else if (dev == priv->mesh_dev) { + if (priv->adapter->mesh_connect_status == LBS_CONNECTED) netif_wake_queue(priv->mesh_dev); } @@ -607,21 +619,21 @@ static void libertas_tx_timeout(struct net_device *dev) /** * @brief This function returns the network statistics * - * @param dev A pointer to wlan_private structure + * @param dev A pointer to struct lbs_private structure * @return A pointer to net_device_stats structure */ -static struct net_device_stats *libertas_get_stats(struct net_device *dev) +static struct net_device_stats *lbs_get_stats(struct net_device *dev) { - wlan_private *priv = (wlan_private *) dev->priv; + struct lbs_private *priv = (struct lbs_private *) dev->priv; return &priv->stats; } -static int libertas_set_mac_address(struct net_device *dev, void *addr) +static int lbs_set_mac_address(struct net_device *dev, void *addr) { int ret = 0; - wlan_private *priv = (wlan_private *) dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *) dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct sockaddr *phwaddr = addr; lbs_deb_enter(LBS_DEB_NET); @@ -637,7 +649,7 @@ static int libertas_set_mac_address(struct net_device *dev, void *addr) lbs_deb_hex(LBS_DEB_NET, "addr", phwaddr->sa_data, ETH_ALEN); memcpy(adapter->current_addr, phwaddr->sa_data, ETH_ALEN); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_MAC_ADDRESS, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -657,7 +669,7 @@ done: return ret; } -static int libertas_copy_multicast_address(wlan_adapter * adapter, +static int lbs_copy_multicast_address(struct lbs_adapter *adapter, struct net_device *dev) { int i = 0; @@ -672,10 +684,10 @@ static int libertas_copy_multicast_address(wlan_adapter * adapter, } -static void libertas_set_multicast_list(struct net_device *dev) +static void lbs_set_multicast_list(struct net_device *dev) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int oldpacketfilter; DECLARE_MAC_BUF(mac); @@ -718,7 +730,7 @@ static void libertas_set_multicast_list(struct net_device *dev) CMD_ACT_MAC_MULTICAST_ENABLE; adapter->nr_of_multicastmacaddr = - libertas_copy_multicast_address(adapter, dev); + lbs_copy_multicast_address(adapter, dev); lbs_deb_net("multicast addresses: %d\n", dev->mc_count); @@ -729,7 +741,7 @@ static void libertas_set_multicast_list(struct net_device *dev) adapter->multicastlist[i])); } /* send multicast addresses to firmware */ - libertas_prepare_and_send_command(priv, + lbs_prepare_and_send_command(priv, CMD_MAC_MULTICAST_ADR, CMD_ACT_SET, 0, 0, NULL); @@ -738,25 +750,25 @@ static void libertas_set_multicast_list(struct net_device *dev) } if (adapter->currentpacketfilter != oldpacketfilter) { - libertas_set_mac_packet_filter(priv); + lbs_set_mac_packet_filter(priv); } lbs_deb_leave(LBS_DEB_NET); } /** - * @brief This function handles the major jobs in the WLAN driver. + * @brief This function handles the major jobs in the LBS driver. * It handles all events generated by firmware, RX data received * from firmware and TX data sent from kernel. * - * @param data A pointer to wlan_thread structure + * @param data A pointer to lbs_thread structure * @return 0 */ -static int libertas_thread(void *data) +static int lbs_thread(void *data) { struct net_device *dev = data; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; wait_queue_t wait; u8 ireg = 0; @@ -836,7 +848,7 @@ static int libertas_thread(void *data) adapter->hisregcpy &= ~MRVDRV_CMD_UPLD_RDY; spin_unlock_irq(&adapter->driver_lock); - libertas_process_rx_command(priv); + lbs_process_rx_command(priv); spin_lock_irq(&adapter->driver_lock); } @@ -853,7 +865,7 @@ static int libertas_thread(void *data) continue; } spin_unlock_irq(&adapter->driver_lock); - libertas_process_event(priv); + lbs_process_event(priv); } else spin_unlock_irq(&adapter->driver_lock); @@ -861,7 +873,7 @@ static int libertas_thread(void *data) if (adapter->psstate == PS_STATE_PRE_SLEEP) { if (!priv->dnld_sent && !adapter->cur_cmd) { if (adapter->connect_status == - LIBERTAS_CONNECTED) { + LBS_CONNECTED) { lbs_deb_thread( "main_thread: PRE_SLEEP--intcounter=%d currenttxskb=%p " "dnld_sent=%d cur_cmd=%p, confirm now\n", @@ -870,7 +882,7 @@ static int libertas_thread(void *data) priv->dnld_sent, adapter->cur_cmd); - libertas_ps_confirm_sleep(priv, + lbs_ps_confirm_sleep(priv, (u16) adapter->psmode); } else { /* workaround for firmware sending @@ -894,15 +906,15 @@ static int libertas_thread(void *data) /* Execute the next command */ if (!priv->dnld_sent && !priv->adapter->cur_cmd) - libertas_execute_next_command(priv); + lbs_execute_next_command(priv); /* Wake-up command waiters which can't sleep in - * libertas_prepare_and_send_command + * lbs_prepare_and_send_command */ if (!adapter->nr_cmd_pending) wake_up_all(&adapter->cmd_pending); - libertas_tx_runqueue(priv); + lbs_tx_runqueue(priv); } del_timer(&adapter->command_timer); @@ -918,13 +930,13 @@ static int libertas_thread(void *data) * HW spec from firmware and set basic parameters to * firmware. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return 0 or -1 */ -static int wlan_setup_firmware(wlan_private * priv) +static int lbs_setup_firmware(struct lbs_private *priv) { int ret = -1; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_mesh_access mesh_access; lbs_deb_enter(LBS_DEB_FW); @@ -934,7 +946,7 @@ static int wlan_setup_firmware(wlan_private * priv) */ memset(adapter->current_addr, 0xff, ETH_ALEN); - ret = libertas_prepare_and_send_command(priv, CMD_GET_HW_SPEC, + ret = lbs_prepare_and_send_command(priv, CMD_GET_HW_SPEC, 0, CMD_OPTION_WAITFORRSP, 0, NULL); if (ret) { @@ -942,10 +954,10 @@ static int wlan_setup_firmware(wlan_private * priv) goto done; } - libertas_set_mac_packet_filter(priv); + lbs_set_mac_packet_filter(priv); /* Get the supported Data rates */ - ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, CMD_ACT_GET_TX_RATE, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -958,7 +970,7 @@ static int wlan_setup_firmware(wlan_private * priv) if (priv->mesh_dev) { memset(&mesh_access, 0, sizeof(mesh_access)); mesh_access.data[0] = cpu_to_le32(0); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_MESH_ACCESS, CMD_ACT_MESH_SET_AUTOSTART_ENABLED, CMD_OPTION_WAITFORRSP, 0, (void *)&mesh_access); @@ -970,7 +982,7 @@ static int wlan_setup_firmware(wlan_private * priv) } /* Set the boot2 version in firmware */ - ret = libertas_prepare_and_send_command(priv, CMD_SET_BOOT2_VER, + ret = lbs_prepare_and_send_command(priv, CMD_SET_BOOT2_VER, 0, CMD_OPTION_WAITFORRSP, 0, NULL); ret = 0; @@ -985,8 +997,8 @@ done: */ static void command_timer_fn(unsigned long data) { - wlan_private *priv = (wlan_private *)data; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = (struct lbs_private *)data; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ctrl_node *ptempnode; struct cmd_ds_command *cmd; unsigned long flags; @@ -1013,16 +1025,16 @@ static void command_timer_fn(unsigned long data) spin_unlock_irqrestore(&adapter->driver_lock, flags); lbs_deb_fw("re-sending same command because of timeout\n"); - libertas_queue_cmd(adapter, ptempnode, 0); + lbs_queue_cmd(adapter, ptempnode, 0); wake_up_interruptible(&priv->waitq); return; } -static int libertas_init_adapter(wlan_private * priv) +static int lbs_init_adapter(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; size_t bufsize; int i, ret = 0; @@ -1043,17 +1055,18 @@ static int libertas_init_adapter(wlan_private * priv) &adapter->network_free_list); } - adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum); - adapter->libertas_ps_confirm_sleep.command = + adapter->lbs_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum); + adapter->lbs_ps_confirm_sleep.command = cpu_to_le16(CMD_802_11_PS_MODE); - adapter->libertas_ps_confirm_sleep.size = + adapter->lbs_ps_confirm_sleep.size = cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep)); - adapter->libertas_ps_confirm_sleep.action = + adapter->lbs_ps_confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); memset(adapter->current_addr, 0xff, ETH_ALEN); - adapter->connect_status = LIBERTAS_DISCONNECTED; + adapter->connect_status = LBS_DISCONNECTED; + adapter->mesh_connect_status = LBS_DISCONNECTED; adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; adapter->mode = IW_MODE_INFRA; adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; @@ -1061,7 +1074,7 @@ static int libertas_init_adapter(wlan_private * priv) adapter->radioon = RADIO_ON; adapter->auto_rate = 1; adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; - adapter->psmode = WLAN802_11POWERMODECAM; + adapter->psmode = LBS802_11POWERMODECAM; adapter->psstate = PS_STATE_FULL_POWER; mutex_init(&adapter->lock); @@ -1081,7 +1094,7 @@ static int libertas_init_adapter(wlan_private * priv) adapter->nr_cmd_pending = 0; /* Allocate the command buffers */ - if (libertas_allocate_cmd_buffer(priv)) { + if (lbs_allocate_cmd_buffer(priv)) { lbs_pr_err("Out of memory allocating command buffers\n"); ret = -1; } @@ -1090,9 +1103,9 @@ out: return ret; } -static void libertas_free_adapter(wlan_private * priv) +static void lbs_free_adapter(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; if (!adapter) { lbs_deb_fw("why double free adapter?\n"); @@ -1100,7 +1113,7 @@ static void libertas_free_adapter(wlan_private * priv) } lbs_deb_fw("free command buffer\n"); - libertas_free_cmd_buffer(priv); + lbs_free_cmd_buffer(priv); lbs_deb_fw("free command_timer\n"); del_timer(&adapter->command_timer); @@ -1117,32 +1130,34 @@ static void libertas_free_adapter(wlan_private * priv) /** * @brief This function adds the card. it will probe the - * card, allocate the wlan_priv and initialize the device. + * card, allocate the lbs_priv and initialize the device. * * @param card A pointer to card - * @return A pointer to wlan_private structure + * @return A pointer to struct lbs_private structure */ -wlan_private *libertas_add_card(void *card, struct device *dmdev) +struct lbs_private *lbs_add_card(void *card, struct device *dmdev) { struct net_device *dev = NULL; - wlan_private *priv = NULL; + struct lbs_private *priv = NULL; lbs_deb_enter(LBS_DEB_NET); /* Allocate an Ethernet device and register it */ - if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { + dev = alloc_etherdev(sizeof(struct lbs_private)); + if (!dev) { lbs_pr_err("init ethX device failed\n"); goto done; } priv = dev->priv; - /* allocate buffer for wlan_adapter */ - if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) { - lbs_pr_err("allocate buffer for wlan_adapter failed\n"); + /* allocate buffer for struct lbs_adapter */ + priv->adapter = kzalloc(sizeof(struct lbs_adapter), GFP_KERNEL); + if (!priv->adapter) { + lbs_pr_err("allocate buffer for struct lbs_adapter failed\n"); goto err_kzalloc; } - if (libertas_init_adapter(priv)) { + if (lbs_init_adapter(priv)) { lbs_pr_err("failed to initialize adapter structure.\n"); goto err_init_adapter; } @@ -1154,46 +1169,46 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) priv->hotplug_device = dmdev; /* Setup the OS Interface to our functions */ - dev->open = libertas_open; - dev->hard_start_xmit = libertas_pre_start_xmit; - dev->stop = libertas_close; - dev->set_mac_address = libertas_set_mac_address; - dev->tx_timeout = libertas_tx_timeout; - dev->get_stats = libertas_get_stats; + dev->open = lbs_open; + dev->hard_start_xmit = lbs_pre_start_xmit; + dev->stop = lbs_close; + dev->set_mac_address = lbs_set_mac_address; + dev->tx_timeout = lbs_tx_timeout; + dev->get_stats = lbs_get_stats; dev->watchdog_timeo = 5 * HZ; - dev->ethtool_ops = &libertas_ethtool_ops; + dev->ethtool_ops = &lbs_ethtool_ops; #ifdef WIRELESS_EXT - dev->wireless_handlers = (struct iw_handler_def *)&libertas_handler_def; + dev->wireless_handlers = (struct iw_handler_def *)&lbs_handler_def; #endif dev->flags |= IFF_BROADCAST | IFF_MULTICAST; - dev->set_multicast_list = libertas_set_multicast_list; + dev->set_multicast_list = lbs_set_multicast_list; SET_NETDEV_DEV(dev, dmdev); priv->rtap_net_dev = NULL; - if (device_create_file(dmdev, &dev_attr_libertas_rtap)) + if (device_create_file(dmdev, &dev_attr_lbs_rtap)) goto err_init_adapter; lbs_deb_thread("Starting main thread...\n"); init_waitqueue_head(&priv->waitq); - priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main"); + priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main"); if (IS_ERR(priv->main_thread)) { lbs_deb_thread("Error creating main thread.\n"); goto err_kthread_run; } - priv->work_thread = create_singlethread_workqueue("libertas_worker"); - INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); - INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker); - INIT_WORK(&priv->sync_channel, libertas_sync_channel); + priv->work_thread = create_singlethread_workqueue("lbs_worker"); + INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); + INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); + INIT_WORK(&priv->sync_channel, lbs_sync_channel); goto done; err_kthread_run: - device_remove_file(dmdev, &dev_attr_libertas_rtap); + device_remove_file(dmdev, &dev_attr_lbs_rtap); err_init_adapter: - libertas_free_adapter(priv); + lbs_free_adapter(priv); err_kzalloc: free_netdev(dev); @@ -1203,29 +1218,29 @@ done: lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv); return priv; } -EXPORT_SYMBOL_GPL(libertas_add_card); +EXPORT_SYMBOL_GPL(lbs_add_card); -int libertas_remove_card(wlan_private *priv) +int lbs_remove_card(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct net_device *dev = priv->dev; union iwreq_data wrqu; lbs_deb_enter(LBS_DEB_MAIN); - libertas_remove_rtap(priv); + lbs_remove_rtap(priv); dev = priv->dev; - device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap); + device_remove_file(priv->hotplug_device, &dev_attr_lbs_rtap); cancel_delayed_work(&priv->scan_work); cancel_delayed_work(&priv->assoc_work); destroy_workqueue(priv->work_thread); - if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) { - adapter->psmode = WLAN802_11POWERMODECAM; - libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); + if (adapter->psmode == LBS802_11POWERMODEMAX_PSP) { + adapter->psmode = LBS802_11POWERMODECAM; + lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); } memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); @@ -1236,7 +1251,7 @@ int libertas_remove_card(wlan_private *priv) adapter->surpriseremoved = 1; kthread_stop(priv->main_thread); - libertas_free_adapter(priv); + lbs_free_adapter(priv); priv->dev = NULL; free_netdev(dev); @@ -1244,10 +1259,10 @@ int libertas_remove_card(wlan_private *priv) lbs_deb_leave(LBS_DEB_MAIN); return 0; } -EXPORT_SYMBOL_GPL(libertas_remove_card); +EXPORT_SYMBOL_GPL(lbs_remove_card); -int libertas_start_card(wlan_private *priv) +int lbs_start_card(struct lbs_private *priv) { struct net_device *dev = priv->dev; int ret = -1; @@ -1255,19 +1270,19 @@ int libertas_start_card(wlan_private *priv) lbs_deb_enter(LBS_DEB_MAIN); /* poke the firmware */ - ret = wlan_setup_firmware(priv); + ret = lbs_setup_firmware(priv); if (ret) goto done; /* init 802.11d */ - libertas_init_11d(priv); + lbs_init_11d(priv); if (register_netdev(dev)) { lbs_pr_err("cannot register ethX device\n"); goto done; } - libertas_debugfs_init_one(priv, dev); + lbs_debugfs_init_one(priv, dev); lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); @@ -1277,10 +1292,10 @@ done: lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_start_card); +EXPORT_SYMBOL_GPL(lbs_start_card); -int libertas_stop_card(wlan_private *priv) +int lbs_stop_card(struct lbs_private *priv) { struct net_device *dev = priv->dev; int ret = -1; @@ -1292,7 +1307,7 @@ int libertas_stop_card(wlan_private *priv) netif_stop_queue(priv->dev); netif_carrier_off(priv->dev); - libertas_debugfs_remove_one(priv); + lbs_debugfs_remove_one(priv); /* Flush pending command nodes */ spin_lock_irqsave(&priv->adapter->driver_lock, flags); @@ -1307,16 +1322,16 @@ int libertas_stop_card(wlan_private *priv) lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_stop_card); +EXPORT_SYMBOL_GPL(lbs_stop_card); /** * @brief This function adds mshX interface * - * @param priv A pointer to the wlan_private structure + * @param priv A pointer to the struct lbs_private structure * @return 0 if successful, -X otherwise */ -int libertas_add_mesh(wlan_private *priv, struct device *dev) +int lbs_add_mesh(struct lbs_private *priv, struct device *dev) { struct net_device *mesh_dev = NULL; int ret = 0; @@ -1332,12 +1347,12 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) mesh_dev->priv = priv; priv->mesh_dev = mesh_dev; - mesh_dev->open = libertas_mesh_open; - mesh_dev->hard_start_xmit = libertas_mesh_pre_start_xmit; - mesh_dev->stop = libertas_mesh_close; - mesh_dev->get_stats = libertas_get_stats; - mesh_dev->set_mac_address = libertas_set_mac_address; - mesh_dev->ethtool_ops = &libertas_ethtool_ops; + mesh_dev->open = lbs_mesh_open; + mesh_dev->hard_start_xmit = lbs_mesh_pre_start_xmit; + mesh_dev->stop = lbs_mesh_close; + mesh_dev->get_stats = lbs_get_stats; + mesh_dev->set_mac_address = lbs_set_mac_address; + mesh_dev->ethtool_ops = &lbs_ethtool_ops; memcpy(mesh_dev->dev_addr, priv->dev->dev_addr, sizeof(priv->dev->dev_addr)); @@ -1353,7 +1368,7 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) goto err_free; } - ret = sysfs_create_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group); + ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); if (ret) goto err_unregister; @@ -1371,10 +1386,10 @@ done: lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_add_mesh); +EXPORT_SYMBOL_GPL(lbs_add_mesh); -void libertas_remove_mesh(wlan_private *priv) +void lbs_remove_mesh(struct lbs_private *priv) { struct net_device *mesh_dev; @@ -1388,7 +1403,7 @@ void libertas_remove_mesh(wlan_private *priv) netif_stop_queue(mesh_dev); netif_carrier_off(priv->mesh_dev); - sysfs_remove_group(&(mesh_dev->dev.kobj), &libertas_mesh_attr_group); + sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group); unregister_netdev(mesh_dev); priv->mesh_dev = NULL ; @@ -1397,7 +1412,7 @@ void libertas_remove_mesh(wlan_private *priv) out: lbs_deb_leave(LBS_DEB_MAIN); } -EXPORT_SYMBOL_GPL(libertas_remove_mesh); +EXPORT_SYMBOL_GPL(lbs_remove_mesh); /** * @brief This function finds the CFP in @@ -1408,7 +1423,7 @@ EXPORT_SYMBOL_GPL(libertas_remove_mesh); * @param cfp_no A pointer to CFP number * @return A pointer to CFP */ -struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *cfp_no) +struct chan_freq_power *lbs_get_region_cfp_table(u8 region, u8 band, int *cfp_no) { int i, end; @@ -1430,9 +1445,9 @@ struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, int *c return NULL; } -int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) +int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; int i = 0; @@ -1444,7 +1459,7 @@ int libertas_set_regiontable(wlan_private * priv, u8 region, u8 band) memset(adapter->region_channel, 0, sizeof(adapter->region_channel)); { - cfp = libertas_get_region_cfp_table(region, band, &cfp_no); + cfp = lbs_get_region_cfp_table(region, band, &cfp_no); if (cfp != NULL) { adapter->region_channel[i].nrcfp = cfp_no; adapter->region_channel[i].CFP = cfp; @@ -1472,13 +1487,13 @@ out: * @param dev A pointer to net_device structure * @return n/a */ -void libertas_interrupt(struct net_device *dev) +void lbs_interrupt(struct net_device *dev) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; lbs_deb_enter(LBS_DEB_THREAD); - lbs_deb_thread("libertas_interrupt: intcounter=%d\n", + lbs_deb_thread("lbs_interrupt: intcounter=%d\n", priv->adapter->intcounter); priv->adapter->intcounter++; @@ -1494,35 +1509,35 @@ void libertas_interrupt(struct net_device *dev) lbs_deb_leave(LBS_DEB_THREAD); } -EXPORT_SYMBOL_GPL(libertas_interrupt); +EXPORT_SYMBOL_GPL(lbs_interrupt); -int libertas_reset_device(wlan_private *priv) +int lbs_reset_device(struct lbs_private *priv) { int ret; lbs_deb_enter(LBS_DEB_MAIN); - ret = libertas_prepare_and_send_command(priv, CMD_802_11_RESET, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RESET, CMD_ACT_HALT, 0, 0, NULL); msleep_interruptible(10); lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_reset_device); +EXPORT_SYMBOL_GPL(lbs_reset_device); -static int libertas_init_module(void) +static int __init lbs_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); - libertas_debugfs_init(); + lbs_debugfs_init(); lbs_deb_leave(LBS_DEB_MAIN); return 0; } -static void libertas_exit_module(void) +static void __exit lbs_exit_module(void) { lbs_deb_enter(LBS_DEB_MAIN); - libertas_debugfs_remove(); + lbs_debugfs_remove(); lbs_deb_leave(LBS_DEB_MAIN); } @@ -1531,32 +1546,32 @@ static void libertas_exit_module(void) * rtap interface support fuctions */ -static int libertas_rtap_open(struct net_device *dev) +static int lbs_rtap_open(struct net_device *dev) { netif_carrier_off(dev); netif_stop_queue(dev); return 0; } -static int libertas_rtap_stop(struct net_device *dev) +static int lbs_rtap_stop(struct net_device *dev) { return 0; } -static int libertas_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int lbs_rtap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { netif_stop_queue(dev); return -EOPNOTSUPP; } -static struct net_device_stats *libertas_rtap_get_stats(struct net_device *dev) +static struct net_device_stats *lbs_rtap_get_stats(struct net_device *dev) { - wlan_private *priv = dev->priv; + struct lbs_private *priv = dev->priv; return &priv->ieee->stats; } -void libertas_remove_rtap(wlan_private *priv) +void lbs_remove_rtap(struct lbs_private *priv) { if (priv->rtap_net_dev == NULL) return; @@ -1565,7 +1580,7 @@ void libertas_remove_rtap(wlan_private *priv) priv->rtap_net_dev = NULL; } -int libertas_add_rtap(wlan_private *priv) +int lbs_add_rtap(struct lbs_private *priv) { int rc = 0; @@ -1582,11 +1597,11 @@ int libertas_add_rtap(wlan_private *priv) strcpy(priv->rtap_net_dev->name, "rtap%d"); priv->rtap_net_dev->type = ARPHRD_IEEE80211_RADIOTAP; - priv->rtap_net_dev->open = libertas_rtap_open; - priv->rtap_net_dev->stop = libertas_rtap_stop; - priv->rtap_net_dev->get_stats = libertas_rtap_get_stats; - priv->rtap_net_dev->hard_start_xmit = libertas_rtap_hard_start_xmit; - priv->rtap_net_dev->set_multicast_list = libertas_set_multicast_list; + priv->rtap_net_dev->open = lbs_rtap_open; + priv->rtap_net_dev->stop = lbs_rtap_stop; + priv->rtap_net_dev->get_stats = lbs_rtap_get_stats; + priv->rtap_net_dev->hard_start_xmit = lbs_rtap_hard_start_xmit; + priv->rtap_net_dev->set_multicast_list = lbs_set_multicast_list; priv->rtap_net_dev->priv = priv; priv->ieee->iw_mode = IW_MODE_MONITOR; @@ -1602,8 +1617,8 @@ int libertas_add_rtap(wlan_private *priv) } -module_init(libertas_init_module); -module_exit(libertas_exit_module); +module_init(lbs_init_module); +module_exit(lbs_exit_module); MODULE_DESCRIPTION("Libertas WLAN Driver Library"); MODULE_AUTHOR("Marvell International Ltd."); diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 0420e5b..fa467df 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c @@ -35,19 +35,20 @@ struct rx80211packethdr { void *eth80211_hdr; } __attribute__ ((packed)); -static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb); +static int process_rxed_802_11_packet(struct lbs_private *priv, + struct sk_buff *skb); /** * @brief This function computes the avgSNR . * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return avgSNR */ -static u8 wlan_getavgsnr(wlan_private * priv) +static u8 lbs_getavgsnr(struct lbs_private *priv) { u8 i; u16 temp = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; if (adapter->numSNRNF == 0) return 0; for (i = 0; i < adapter->numSNRNF; i++) @@ -59,14 +60,14 @@ static u8 wlan_getavgsnr(wlan_private * priv) /** * @brief This function computes the AvgNF * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return AvgNF */ -static u8 wlan_getavgnf(wlan_private * priv) +static u8 lbs_getavgnf(struct lbs_private *priv) { u8 i; u16 temp = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; if (adapter->numSNRNF == 0) return 0; for (i = 0; i < adapter->numSNRNF; i++) @@ -78,13 +79,13 @@ static u8 wlan_getavgnf(wlan_private * priv) /** * @brief This function save the raw SNR/NF to our internel buffer * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param prxpd A pointer to rxpd structure of received packet * @return n/a */ -static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd) +static void lbs_save_rawSNRNF(struct lbs_private *priv, struct rxpd *p_rx_pd) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; if (adapter->numSNRNF < DEFAULT_DATA_AVG_FACTOR) adapter->numSNRNF++; adapter->rawSNR[adapter->nextSNRNF] = p_rx_pd->snr; @@ -98,13 +99,13 @@ static void wlan_save_rawSNRNF(wlan_private * priv, struct rxpd *p_rx_pd) /** * @brief This function computes the RSSI in received packet. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param prxpd A pointer to rxpd structure of received packet * @return n/a */ -static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) +static void lbs_compute_rssi(struct lbs_private *priv, struct rxpd *p_rx_pd) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_RX); @@ -115,10 +116,10 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) adapter->SNR[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->snr; adapter->NF[TYPE_RXPD][TYPE_NOAVG] = p_rx_pd->nf; - wlan_save_rawSNRNF(priv, p_rx_pd); + lbs_save_rawSNRNF(priv, p_rx_pd); - adapter->SNR[TYPE_RXPD][TYPE_AVG] = wlan_getavgsnr(priv) * AVG_SCALE; - adapter->NF[TYPE_RXPD][TYPE_AVG] = wlan_getavgnf(priv) * AVG_SCALE; + adapter->SNR[TYPE_RXPD][TYPE_AVG] = lbs_getavgsnr(priv) * AVG_SCALE; + adapter->NF[TYPE_RXPD][TYPE_AVG] = lbs_getavgnf(priv) * AVG_SCALE; lbs_deb_rx("after computing SNR: SNR-avg = %d, NF-avg = %d\n", adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE, adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE); @@ -134,11 +135,11 @@ static void wlan_compute_rssi(wlan_private * priv, struct rxpd *p_rx_pd) lbs_deb_leave(LBS_DEB_RX); } -void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) +void lbs_upload_rx_packet(struct lbs_private *priv, struct sk_buff *skb) { lbs_deb_rx("skb->data %p\n", skb->data); - if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode != LBS_MONITOR_OFF) { skb->protocol = eth_type_trans(skb, priv->rtap_net_dev); } else { if (priv->mesh_dev && IS_MESH_FRAME(skb)) @@ -154,13 +155,13 @@ void libertas_upload_rx_packet(wlan_private * priv, struct sk_buff *skb) * @brief This function processes received packet and forwards it * to kernel/upper layer * - * @param priv A pointer to wlan_private + * @param priv A pointer to struct lbs_private * @param skb A pointer to skb which includes the received packet * @return 0 or -1 */ -int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) +int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct rxpackethdr *p_rx_pkt; @@ -173,7 +174,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) lbs_deb_enter(LBS_DEB_RX); - if (priv->adapter->monitormode != WLAN_MONITOR_OFF) + if (priv->adapter->monitormode != LBS_MONITOR_OFF) return process_rxed_802_11_packet(priv, skb); p_rx_pkt = (struct rxpackethdr *) skb->data; @@ -258,22 +259,22 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb) * only if the rate is auto */ if (adapter->auto_rate) - adapter->cur_rate = libertas_fw_index_to_data_rate(p_rx_pd->rx_rate); + adapter->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); - wlan_compute_rssi(priv, p_rx_pd); + lbs_compute_rssi(priv, p_rx_pd); lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; - libertas_upload_rx_packet(priv, skb); + lbs_upload_rx_packet(priv, skb); ret = 0; done: lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret); return ret; } -EXPORT_SYMBOL_GPL(libertas_process_rxed_packet); +EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); /** * @brief This function converts Tx/Rx rates from the Marvell WLAN format @@ -319,13 +320,14 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) * @brief This function processes a received 802.11 packet and forwards it * to kernel/upper layer * - * @param priv A pointer to wlan_private + * @param priv A pointer to struct lbs_private * @param skb A pointer to skb which includes the received packet * @return 0 or -1 */ -static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) +static int process_rxed_802_11_packet(struct lbs_private *priv, + struct sk_buff *skb) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct rx80211packethdr *p_rx_pkt; @@ -359,7 +361,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); /* create the exported radio header */ - if(priv->adapter->monitormode == WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode == LBS_MONITOR_OFF) { /* no radio header */ /* chop the rxpd */ skb_pull(skb, sizeof(struct rxpd)); @@ -409,15 +411,15 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb) * only if the rate is auto */ if (adapter->auto_rate) - adapter->cur_rate = libertas_fw_index_to_data_rate(prxpd->rx_rate); + adapter->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); - wlan_compute_rssi(priv, prxpd); + lbs_compute_rssi(priv, prxpd); lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); priv->stats.rx_bytes += skb->len; priv->stats.rx_packets++; - libertas_upload_rx_packet(priv, skb); + lbs_upload_rx_packet(priv, skb); ret = 0; diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index ad1e67d..236bc7d 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c @@ -39,9 +39,8 @@ //! Memory needed to store a max number/size SSID TLV for a firmware scan #define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) -//! Maximum memory needed for a wlan_scan_cmd_config with all TLVs at max -#define MAX_SCAN_CFG_ALLOC (sizeof(struct wlan_scan_cmd_config) \ - + sizeof(struct mrvlietypes_numprobes) \ +//! Maximum memory needed for a lbs_scan_cmd_config with all TLVs at max +#define MAX_SCAN_CFG_ALLOC (sizeof(struct lbs_scan_cmd_config) \ + CHAN_TLV_MAX_SIZE \ + SSID_TLV_MAX_SIZE) @@ -80,7 +79,7 @@ static inline void clear_bss_descriptor (struct bss_descriptor * bss) memset(bss, 0, offsetof(struct bss_descriptor, list)); } -static inline int match_bss_no_security(struct wlan_802_11_security * secinfo, +static inline int match_bss_no_security(struct lbs_802_11_security *secinfo, struct bss_descriptor * match_bss) { if ( !secinfo->wep_enabled @@ -94,7 +93,7 @@ static inline int match_bss_no_security(struct wlan_802_11_security * secinfo, return 0; } -static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo, +static inline int match_bss_static_wep(struct lbs_802_11_security *secinfo, struct bss_descriptor * match_bss) { if ( secinfo->wep_enabled @@ -106,7 +105,7 @@ static inline int match_bss_static_wep(struct wlan_802_11_security * secinfo, return 0; } -static inline int match_bss_wpa(struct wlan_802_11_security * secinfo, +static inline int match_bss_wpa(struct lbs_802_11_security *secinfo, struct bss_descriptor * match_bss) { if ( !secinfo->wep_enabled @@ -121,7 +120,7 @@ static inline int match_bss_wpa(struct wlan_802_11_security * secinfo, return 0; } -static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo, +static inline int match_bss_wpa2(struct lbs_802_11_security *secinfo, struct bss_descriptor * match_bss) { if ( !secinfo->wep_enabled @@ -136,7 +135,7 @@ static inline int match_bss_wpa2(struct wlan_802_11_security * secinfo, return 0; } -static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo, +static inline int match_bss_dynamic_wep(struct lbs_802_11_security *secinfo, struct bss_descriptor * match_bss) { if ( !secinfo->wep_enabled @@ -163,13 +162,13 @@ static inline int match_bss_dynamic_wep(struct wlan_802_11_security * secinfo, * 0 0 0 0 !=NONE 1 0 0 yes Dynamic WEP * * - * @param adapter A pointer to wlan_adapter + * @param adapter A pointer to struct lbs_adapter * @param index Index in scantable to check against current driver settings * @param mode Network mode: Infrastructure or IBSS * * @return Index in scantable, or error code if negative */ -static int is_network_compatible(wlan_adapter * adapter, +static int is_network_compatible(struct lbs_adapter *adapter, struct bss_descriptor * bss, u8 mode) { int matched = 0; @@ -235,7 +234,7 @@ done: * * @return 0--ssid is same, otherwise is different */ -int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) +int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) { if (ssid1_len != ssid2_len) return -1; @@ -256,13 +255,13 @@ int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) /** * @brief Create a channel list for the driver to scan based on region info * - * Only used from wlan_scan_setup_scan_config() + * Only used from lbs_scan_setup_scan_config() * * Use the driver region/band information to construct a comprehensive list * of channels to scan. This routine is used for any scan that is not * provided a specific channel list to scan. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param scanchanlist Output parameter: resulting channel list to scan * @param filteredscan Flag indicating whether or not a BSSID or SSID filter * is being sent in the command to firmware. Used to @@ -272,12 +271,12 @@ int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len) * * @return void */ -static void wlan_scan_create_channel_list(wlan_private * priv, +static void lbs_scan_create_channel_list(struct lbs_private *priv, struct chanscanparamset * scanchanlist, u8 filteredscan) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct region_channel *scanregion; struct chan_freq_power *cfp; int rgnidx; @@ -297,7 +296,8 @@ static void wlan_scan_create_channel_list(wlan_private * priv, for (rgnidx = 0; rgnidx < ARRAY_SIZE(adapter->region_channel); rgnidx++) { if (priv->adapter->enable11d && - adapter->connect_status != LIBERTAS_CONNECTED) { + (adapter->connect_status != LBS_CONNECTED) && + (adapter->mesh_connect_status != LBS_CONNECTED)) { /* Scan all the supported chan for the first scan */ if (!adapter->universal_channel[rgnidx].valid) continue; @@ -319,7 +319,7 @@ static void wlan_scan_create_channel_list(wlan_private * priv, if (priv->adapter->enable11d) { scantype = - libertas_get_scan_type_11d(cfp->channel, + lbs_get_scan_type_11d(cfp->channel, &adapter-> parsed_region_chan); } @@ -357,24 +357,26 @@ static void wlan_scan_create_channel_list(wlan_private * priv, /* Delayed partial scan worker */ -void libertas_scan_worker(struct work_struct *work) +void lbs_scan_worker(struct work_struct *work) { - wlan_private *priv = container_of(work, wlan_private, scan_work.work); + struct lbs_private *priv = container_of(work, + struct lbs_private, + scan_work.work); - wlan_scan_networks(priv, NULL, 0); + lbs_scan_networks(priv, NULL, 0); } /** - * @brief Construct a wlan_scan_cmd_config structure to use in issue scan cmds + * @brief Construct a lbs_scan_cmd_config structure to use in issue scan cmds * - * Application layer or other functions can invoke wlan_scan_networks - * with a scan configuration supplied in a wlan_ioctl_user_scan_cfg struct. - * This structure is used as the basis of one or many wlan_scan_cmd_config + * Application layer or other functions can invoke lbs_scan_networks + * with a scan configuration supplied in a lbs_ioctl_user_scan_cfg struct. + * This structure is used as the basis of one or many lbs_scan_cmd_config * commands that are sent to the command processing module and sent to * firmware. * - * Create a wlan_scan_cmd_config based on the following user supplied + * Create a lbs_scan_cmd_config based on the following user supplied * parameters (if present): * - SSID filter * - BSSID filter @@ -382,10 +384,9 @@ void libertas_scan_worker(struct work_struct *work) * - channel list * * If the SSID or BSSID filter is not present, disable/clear the filter. - * If the number of probes is not set, use the adapter default setting * Qualify the channel * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param puserscanin NULL or pointer to scan configuration parameters * @param ppchantlvout Output parameter: Pointer to the start of the * channel TLV portion of the output scan config @@ -403,25 +404,18 @@ void libertas_scan_worker(struct work_struct *work) * * @return resulting scan configuration */ -static struct wlan_scan_cmd_config * -wlan_scan_setup_scan_config(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin, +static struct lbs_scan_cmd_config * +lbs_scan_setup_scan_config(struct lbs_private *priv, + const struct lbs_ioctl_user_scan_cfg *puserscanin, struct mrvlietypes_chanlistparamset ** ppchantlvout, struct chanscanparamset * pscanchanlist, int *pmaxchanperscan, u8 * pfilteredscan, u8 * pscancurrentonly) { - struct mrvlietypes_numprobes *pnumprobestlv; struct mrvlietypes_ssidparamset *pssidtlv; - struct wlan_scan_cmd_config * pscancfgout = NULL; + struct lbs_scan_cmd_config *pscancfgout = NULL; u8 *ptlvpos; - u16 numprobes; - int chanidx; - int scantype; - int scandur; - int channel; - int radiotype; lbs_deb_enter(LBS_DEB_SCAN); @@ -465,9 +459,6 @@ wlan_scan_setup_scan_config(wlan_private * priv, pscancfgout->bsstype = puserscanin->bsstype ? puserscanin->bsstype : CMD_BSS_TYPE_ANY; - /* Set the number of probes to send, use adapter setting if unset */ - numprobes = puserscanin->numprobes ? puserscanin->numprobes : 0; - /* * Set the BSSID filter to the incoming configuration, * if non-zero. If not set, it will remain disabled (all zeros). @@ -499,79 +490,18 @@ wlan_scan_setup_scan_config(wlan_private * priv, } } else { pscancfgout->bsstype = CMD_BSS_TYPE_ANY; - numprobes = 0; - } - - /* If the input config or adapter has the number of Probes set, add tlv */ - if (numprobes) { - pnumprobestlv = (struct mrvlietypes_numprobes *) ptlvpos; - pnumprobestlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES); - pnumprobestlv->header.len = cpu_to_le16(2); - pnumprobestlv->numprobes = cpu_to_le16(numprobes); - - ptlvpos += sizeof(*pnumprobestlv); } /* * Set the output for the channel TLV to the address in the tlv buffer - * past any TLVs that were added in this fuction (SSID, numprobes). + * past any TLVs that were added in this fuction (SSID). * channel TLVs will be added past this for each scan command, preserving * the TLVs that were previously added. */ *ppchantlvout = (struct mrvlietypes_chanlistparamset *) ptlvpos; - if (!puserscanin || !puserscanin->chanlist[0].channumber) { - /* Create a default channel scan list */ - lbs_deb_scan("creating full region channel list\n"); - wlan_scan_create_channel_list(priv, pscanchanlist, - *pfilteredscan); - goto out; - } - - for (chanidx = 0; - chanidx < WLAN_IOCTL_USER_SCAN_CHAN_MAX - && puserscanin->chanlist[chanidx].channumber; chanidx++) { - - channel = puserscanin->chanlist[chanidx].channumber; - (pscanchanlist + chanidx)->channumber = channel; - - radiotype = puserscanin->chanlist[chanidx].radiotype; - (pscanchanlist + chanidx)->radiotype = radiotype; - - scantype = puserscanin->chanlist[chanidx].scantype; - - if (scantype == CMD_SCAN_TYPE_PASSIVE) { - (pscanchanlist + - chanidx)->chanscanmode.passivescan = 1; - } else { - (pscanchanlist + - chanidx)->chanscanmode.passivescan = 0; - } - - if (puserscanin->chanlist[chanidx].scantime) { - scandur = puserscanin->chanlist[chanidx].scantime; - } else { - if (scantype == CMD_SCAN_TYPE_PASSIVE) { - scandur = MRVDRV_PASSIVE_SCAN_CHAN_TIME; - } else { - scandur = MRVDRV_ACTIVE_SCAN_CHAN_TIME; - } - } - - (pscanchanlist + chanidx)->minscantime = - cpu_to_le16(scandur); - (pscanchanlist + chanidx)->maxscantime = - cpu_to_le16(scandur); - } - - /* Check if we are only scanning the current channel */ - if ((chanidx == 1) && - (puserscanin->chanlist[0].channumber == - priv->adapter->curbssparams.channel)) { - *pscancurrentonly = 1; - lbs_deb_scan("scanning current channel only"); - } - + lbs_scan_create_channel_list(priv, pscanchanlist, + *pfilteredscan); out: return pscancfgout; } @@ -579,14 +509,14 @@ out: /** * @brief Construct and send multiple scan config commands to the firmware * - * Only used from wlan_scan_networks() + * Only used from lbs_scan_networks() * - * Previous routines have created a wlan_scan_cmd_config with any requested + * Previous routines have created a lbs_scan_cmd_config with any requested * TLVs. This function splits the channel TLV into maxchanperscan lists * and sends the portion of the channel TLV along with the other TLVs - * to the wlan_cmd routines for execution in the firmware. + * to the lbs_cmd routines for execution in the firmware. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param maxchanperscan Maximum number channels to be included in each * scan command sent to firmware * @param filteredscan Flag indicating whether or not a BSSID or SSID @@ -600,13 +530,13 @@ out: * * @return 0 or error return otherwise */ -static int wlan_scan_channel_list(wlan_private * priv, +static int lbs_scan_channel_list(struct lbs_private *priv, int maxchanperscan, u8 filteredscan, - struct wlan_scan_cmd_config * pscancfgout, + struct lbs_scan_cmd_config *pscancfgout, struct mrvlietypes_chanlistparamset * pchantlvout, struct chanscanparamset * pscanchanlist, - const struct wlan_ioctl_user_scan_cfg * puserscanin, + const struct lbs_ioctl_user_scan_cfg *puserscanin, int full_scan) { struct chanscanparamset *ptmpchan; @@ -720,7 +650,7 @@ static int wlan_scan_channel_list(wlan_private * priv, } /* Send the scan command to the firmware with the specified cfg */ - ret = libertas_prepare_and_send_command(priv, CMD_802_11_SCAN, 0, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SCAN, 0, 0, 0, pscancfgout); if (scanned >= 2 && !full_scan) { ret = 0; @@ -751,10 +681,10 @@ out: } /* - * Only used from wlan_scan_networks() + * Only used from lbs_scan_networks() */ -static void clear_selected_scan_list_entries(wlan_adapter *adapter, - const struct wlan_ioctl_user_scan_cfg *scan_cfg) +static void clear_selected_scan_list_entries(struct lbs_adapter *adapter, + const struct lbs_ioctl_user_scan_cfg *scan_cfg) { struct bss_descriptor *bss; struct bss_descriptor *safe; @@ -812,21 +742,21 @@ out: * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param puserscanin Pointer to the input configuration for the requested * scan. * @param full_scan ??? * * @return 0 or < 0 if error */ -int wlan_scan_networks(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin, +int lbs_scan_networks(struct lbs_private *priv, + const struct lbs_ioctl_user_scan_cfg *puserscanin, int full_scan) { - wlan_adapter * adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct mrvlietypes_chanlistparamset *pchantlvout; struct chanscanparamset * scan_chan_list = NULL; - struct wlan_scan_cmd_config * scan_cfg = NULL; + struct lbs_scan_cmd_config *scan_cfg = NULL; u8 filteredscan; u8 scancurrentchanonly; int maxchanperscan; @@ -846,13 +776,13 @@ int wlan_scan_networks(wlan_private * priv, cancel_delayed_work(&priv->scan_work); scan_chan_list = kzalloc(sizeof(struct chanscanparamset) * - WLAN_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); + LBS_IOCTL_USER_SCAN_CHAN_MAX, GFP_KERNEL); if (scan_chan_list == NULL) { ret = -ENOMEM; goto out; } - scan_cfg = wlan_scan_setup_scan_config(priv, + scan_cfg = lbs_scan_setup_scan_config(priv, puserscanin, &pchantlvout, scan_chan_list, @@ -876,7 +806,7 @@ int wlan_scan_networks(wlan_private * priv, } } - ret = wlan_scan_channel_list(priv, + ret = lbs_scan_channel_list(priv, maxchanperscan, filteredscan, scan_cfg, @@ -897,13 +827,14 @@ int wlan_scan_networks(wlan_private * priv, mutex_unlock(&adapter->lock); #endif - if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->connect_status == LBS_CONNECTED) { netif_carrier_on(priv->dev); netif_wake_queue(priv->dev); - if (priv->mesh_dev) { - netif_carrier_on(priv->mesh_dev); - netif_wake_queue(priv->mesh_dev); - } + } + + if (priv->mesh_dev && (adapter->mesh_connect_status == LBS_CONNECTED)) { + netif_carrier_on(priv->mesh_dev); + netif_wake_queue(priv->mesh_dev); } out: @@ -928,7 +859,7 @@ out: * * @return 0 or -1 */ -static int libertas_process_bss(struct bss_descriptor * bss, +static int lbs_process_bss(struct bss_descriptor *bss, u8 ** pbeaconinfo, int *bytesleft) { struct ieeetypes_fhparamset *pFH; @@ -1139,7 +1070,7 @@ static int libertas_process_bss(struct bss_descriptor * bss, /* Timestamp */ bss->last_scanned = jiffies; - libertas_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); + lbs_unset_basic_rate_flags(bss->rates, sizeof(bss->rates)); ret = 0; @@ -1153,13 +1084,13 @@ done: * * Used in association code * - * @param adapter A pointer to wlan_adapter + * @param adapter A pointer to struct lbs_adapter * @param bssid BSSID to find in the scan list * @param mode Network mode: Infrastructure or IBSS * * @return index in BSSID list, or error return code (< 0) */ -struct bss_descriptor *libertas_find_bssid_in_list(wlan_adapter * adapter, +struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_adapter *adapter, u8 * bssid, u8 mode) { struct bss_descriptor * iter_bss; @@ -1205,14 +1136,14 @@ out: * * Used in association code * - * @param adapter A pointer to wlan_adapter + * @param adapter A pointer to struct lbs_adapter * @param ssid SSID to find in the list * @param bssid BSSID to qualify the SSID selection (if provided) * @param mode Network mode: Infrastructure or IBSS * * @return index in BSSID list */ -struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, +struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_adapter *adapter, u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, int channel) { @@ -1230,7 +1161,7 @@ struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, || (iter_bss->last_scanned < tmp_oldest->last_scanned)) tmp_oldest = iter_bss; - if (libertas_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, + if (lbs_ssid_cmp(iter_bss->ssid, iter_bss->ssid_len, ssid, ssid_len) != 0) continue; /* ssid doesn't match */ if (bssid && compare_ether_addr(iter_bss->bssid, bssid) != 0) @@ -1277,12 +1208,13 @@ out: * Search the scan table for the best SSID that also matches the current * adapter network preference (infrastructure or adhoc) * - * @param adapter A pointer to wlan_adapter + * @param adapter A pointer to struct lbs_adapter * * @return index in BSSID list */ -static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * adapter, - u8 mode) +static struct bss_descriptor *lbs_find_best_ssid_in_list( + struct lbs_adapter *adapter, + u8 mode) { u8 bestrssi = 0; struct bss_descriptor * iter_bss; @@ -1323,27 +1255,27 @@ static struct bss_descriptor * libertas_find_best_ssid_in_list(wlan_adapter * ad * * Used from association worker. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param pSSID A pointer to AP's ssid * * @return 0--success, otherwise--fail */ -int libertas_find_best_network_ssid(wlan_private * priv, +int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int ret = -1; struct bss_descriptor * found; lbs_deb_enter(LBS_DEB_SCAN); - wlan_scan_networks(priv, NULL, 1); + lbs_scan_networks(priv, NULL, 1); if (adapter->surpriseremoved) goto out; wait_event_interruptible(adapter->cmd_pending, !adapter->nr_cmd_pending); - found = libertas_find_best_ssid_in_list(adapter, preferred_mode); + found = lbs_find_best_ssid_in_list(adapter, preferred_mode); if (found && (found->ssid_len > 0)) { memcpy(out_ssid, &found->ssid, IW_ESSID_MAX_SIZE); *out_ssid_len = found->ssid_len; @@ -1366,11 +1298,11 @@ out: * * @return 0 --success, otherwise fail */ -int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, +int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_SCAN); @@ -1392,7 +1324,7 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, * * Used in association code and from debugfs * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param ssid A pointer to the SSID to scan for * @param ssid_len Length of the SSID * @param clear_ssid Should existing scan results with this SSID @@ -1402,11 +1334,11 @@ int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, * * @return 0-success, otherwise fail */ -int libertas_send_specific_ssid_scan(wlan_private * priv, +int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, u8 ssid_len, u8 clear_ssid) { - wlan_adapter *adapter = priv->adapter; - struct wlan_ioctl_user_scan_cfg scancfg; + struct lbs_adapter *adapter = priv->adapter; + struct lbs_ioctl_user_scan_cfg scancfg; int ret = 0; lbs_deb_enter_args(LBS_DEB_SCAN, "SSID '%s', clear %d", @@ -1420,7 +1352,7 @@ int libertas_send_specific_ssid_scan(wlan_private * priv, scancfg.ssid_len = ssid_len; scancfg.clear_ssid = clear_ssid; - wlan_scan_networks(priv, &scancfg, 1); + lbs_scan_networks(priv, &scancfg, 1); if (adapter->surpriseremoved) { ret = -1; goto out; @@ -1443,11 +1375,11 @@ out: #define MAX_CUSTOM_LEN 64 -static inline char *libertas_translate_scan(wlan_private *priv, +static inline char *lbs_translate_scan(struct lbs_private *priv, char *start, char *stop, struct bss_descriptor *bss) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct chan_freq_power *cfp; char *current_val; /* For rates */ struct iw_event iwe; /* Temporary buffer */ @@ -1459,7 +1391,7 @@ static inline char *libertas_translate_scan(wlan_private *priv, lbs_deb_enter(LBS_DEB_SCAN); - cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, bss->channel); + cfp = lbs_find_cfp_by_band_and_channel(adapter, 0, bss->channel); if (!cfp) { lbs_deb_scan("Invalid channel number %d\n", bss->channel); start = NULL; @@ -1515,7 +1447,7 @@ static inline char *libertas_translate_scan(wlan_private *priv, */ if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate - && !libertas_ssid_cmp(adapter->curbssparams.ssid, + && !lbs_ssid_cmp(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len, bss->ssid, bss->ssid_len)) { int snr, nf; @@ -1549,7 +1481,7 @@ static inline char *libertas_translate_scan(wlan_private *priv, stop, &iwe, IW_EV_PARAM_LEN); } if ((bss->mode == IW_MODE_ADHOC) - && !libertas_ssid_cmp(adapter->curbssparams.ssid, + && !lbs_ssid_cmp(adapter->curbssparams.ssid, adapter->curbssparams.ssid_len, bss->ssid, bss->ssid_len) && adapter->adhoccreate) { @@ -1606,12 +1538,12 @@ out: * * @return 0 --success, otherwise fail */ -int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, +int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { #define SCAN_ITEM_SIZE 128 - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int err = 0; char *ev = extra; char *stop = ev + dwrq->length; @@ -1622,7 +1554,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, /* Update RSSI if current BSS is a locally created ad-hoc BSS */ if ((adapter->mode == IW_MODE_ADHOC) && adapter->adhoccreate) { - libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, + lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, CMD_OPTION_WAITFORRSP, 0, NULL); } @@ -1650,7 +1582,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, } /* Translate to WE format this entry */ - next_ev = libertas_translate_scan(priv, ev, stop, iter_bss); + next_ev = lbs_translate_scan(priv, ev, stop, iter_bss); if (next_ev == NULL) continue; ev = next_ev; @@ -1677,24 +1609,24 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, /** * @brief Prepare a scan command to be sent to the firmware * - * Called from libertas_prepare_and_send_command() in cmd.c + * Called from lbs_prepare_and_send_command() in cmd.c * * Sends a fixed lenght data part (specifying the BSS type and BSSID filters) * as well as a variable number/length of TLVs to the firmware. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param cmd A pointer to cmd_ds_command structure to be sent to * firmware with the cmd_DS_801_11_SCAN structure - * @param pdata_buf Void pointer cast of a wlan_scan_cmd_config struct used + * @param pdata_buf Void pointer cast of a lbs_scan_cmd_config struct used * to set the fields/TLVs for the command sent to firmware * * @return 0 or -1 */ -int libertas_cmd_80211_scan(wlan_private * priv, +int lbs_cmd_80211_scan(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf) { struct cmd_ds_802_11_scan *pscan = &cmd->params.scan; - struct wlan_scan_cmd_config *pscancfg = pdata_buf; + struct lbs_scan_cmd_config *pscancfg = pdata_buf; lbs_deb_enter(LBS_DEB_SCAN); @@ -1750,14 +1682,14 @@ static inline int is_same_network(struct bss_descriptor *src, * | bufsize and sizeof the fixed fields above) | * .-----------------------------------------------------------. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param resp A pointer to cmd_ds_command * * @return 0 or -1 */ -int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) +int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct cmd_ds_802_11_scan_rsp *pscan; struct bss_descriptor * iter_bss; struct bss_descriptor * safe; @@ -1821,7 +1753,7 @@ int libertas_ret_80211_scan(wlan_private * priv, struct cmd_ds_command *resp) /* Process the data fields and IEs returned for this BSS */ memset(&new, 0, sizeof (struct bss_descriptor)); - if (libertas_process_bss(&new, &pbssinfo, &bytesleft) != 0) { + if (lbs_process_bss(&new, &pbssinfo, &bytesleft) != 0) { /* error parsing the scan response, skipped */ lbs_deb_scan("SCAN_RESP: process_bss returned ERROR\n"); continue; diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h index c29c031..9b62e2b 100644 --- a/drivers/net/wireless/libertas/scan.h +++ b/drivers/net/wireless/libertas/scan.h @@ -2,49 +2,51 @@ * Interface for the wlan network scan routines * * Driver interface functions and type declarations for the scan module - * implemented in wlan_scan.c. + * implemented in scan.c. */ -#ifndef _WLAN_SCAN_H -#define _WLAN_SCAN_H +#ifndef _LBS_SCAN_H +#define _LBS_SCAN_H #include #include "hostcmd.h" +struct lbs_adapter; + /** * @brief Maximum number of channels that can be sent in a setuserscan ioctl * - * @sa wlan_ioctl_user_scan_cfg + * @sa lbs_ioctl_user_scan_cfg */ -#define WLAN_IOCTL_USER_SCAN_CHAN_MAX 50 +#define LBS_IOCTL_USER_SCAN_CHAN_MAX 50 -//! Infrastructure BSS scan type in wlan_scan_cmd_config -#define WLAN_SCAN_BSS_TYPE_BSS 1 +//! Infrastructure BSS scan type in lbs_scan_cmd_config +#define LBS_SCAN_BSS_TYPE_BSS 1 -//! Adhoc BSS scan type in wlan_scan_cmd_config -#define WLAN_SCAN_BSS_TYPE_IBSS 2 +//! Adhoc BSS scan type in lbs_scan_cmd_config +#define LBS_SCAN_BSS_TYPE_IBSS 2 -//! Adhoc or Infrastructure BSS scan type in wlan_scan_cmd_config, no filter -#define WLAN_SCAN_BSS_TYPE_ANY 3 +//! Adhoc or Infrastructure BSS scan type in lbs_scan_cmd_config, no filter +#define LBS_SCAN_BSS_TYPE_ANY 3 /** * @brief Structure used internally in the wlan driver to configure a scan. * * Sent to the command processing module to configure the firmware - * scan command prepared by libertas_cmd_80211_scan. + * scan command prepared by lbs_cmd_80211_scan. * - * @sa wlan_scan_networks + * @sa lbs_scan_networks * */ -struct wlan_scan_cmd_config { +struct lbs_scan_cmd_config { /** * @brief BSS type to be sent in the firmware command * * Field can be used to restrict the types of networks returned in the * scan. valid settings are: * - * - WLAN_SCAN_BSS_TYPE_BSS (infrastructure) - * - WLAN_SCAN_BSS_TYPE_IBSS (adhoc) - * - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) + * - LBS_SCAN_BSS_TYPE_BSS (infrastructure) + * - LBS_SCAN_BSS_TYPE_IBSS (adhoc) + * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) */ u8 bsstype; @@ -68,12 +70,12 @@ struct wlan_scan_cmd_config { }; /** - * @brief IOCTL channel sub-structure sent in wlan_ioctl_user_scan_cfg + * @brief IOCTL channel sub-structure sent in lbs_ioctl_user_scan_cfg * * Multiple instances of this structure are included in the IOCTL command * to configure a instance of a scan on the specific channel. */ -struct wlan_ioctl_user_scan_chan { +struct lbs_ioctl_user_scan_chan { u8 channumber; //!< channel Number to scan u8 radiotype; //!< Radio type: 'B/G' band = 0, 'A' band = 1 u8 scantype; //!< Scan type: Active = 0, Passive = 1 @@ -83,31 +85,26 @@ struct wlan_ioctl_user_scan_chan { /** * @brief IOCTL input structure to configure an immediate scan cmd to firmware * - * Used in the setuserscan (WLAN_SET_USER_SCAN) private ioctl. Specifies + * Used in the setuserscan (LBS_SET_USER_SCAN) private ioctl. Specifies * a number of parameters to be used in general for the scan as well - * as a channel list (wlan_ioctl_user_scan_chan) for each scan period + * as a channel list (lbs_ioctl_user_scan_chan) for each scan period * desired. * - * @sa libertas_set_user_scan_ioctl + * @sa lbs_set_user_scan_ioctl */ -struct wlan_ioctl_user_scan_cfg { +struct lbs_ioctl_user_scan_cfg { /** * @brief BSS type to be sent in the firmware command * * Field can be used to restrict the types of networks returned in the * scan. valid settings are: * - * - WLAN_SCAN_BSS_TYPE_BSS (infrastructure) - * - WLAN_SCAN_BSS_TYPE_IBSS (adhoc) - * - WLAN_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) + * - LBS_SCAN_BSS_TYPE_BSS (infrastructure) + * - LBS_SCAN_BSS_TYPE_IBSS (adhoc) + * - LBS_SCAN_BSS_TYPE_ANY (unrestricted, adhoc and infrastructure) */ u8 bsstype; - /** - * @brief Configure the number of probe requests for active chan scans - */ - u8 numprobes; - /** * @brief BSSID filter sent in the firmware command to limit the results */ @@ -124,11 +121,6 @@ struct wlan_ioctl_user_scan_cfg { /* Clear existing scan results matching this SSID */ u8 clear_ssid; - - /** - * @brief Variable number (fixed maximum) of channels to scan up - */ - struct wlan_ioctl_user_scan_chan chanlist[WLAN_IOCTL_USER_SCAN_CHAN_MAX]; }; /** @@ -174,30 +166,30 @@ struct bss_descriptor { struct list_head list; }; -int libertas_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); +int lbs_ssid_cmp(u8 *ssid1, u8 ssid1_len, u8 *ssid2, u8 ssid2_len); -struct bss_descriptor * libertas_find_ssid_in_list(wlan_adapter * adapter, - u8 *ssid, u8 ssid_len, u8 * bssid, u8 mode, - int channel); +struct bss_descriptor *lbs_find_ssid_in_list(struct lbs_adapter *adapter, + u8 *ssid, u8 ssid_len, u8 *bssid, u8 mode, + int channel); -struct bss_descriptor * libertas_find_bssid_in_list(wlan_adapter * adapter, - u8 * bssid, u8 mode); +struct bss_descriptor *lbs_find_bssid_in_list(struct lbs_adapter *adapter, + u8 *bssid, u8 mode); -int libertas_find_best_network_ssid(wlan_private * priv, u8 *out_ssid, +int lbs_find_best_network_ssid(struct lbs_private *priv, u8 *out_ssid, u8 *out_ssid_len, u8 preferred_mode, u8 *out_mode); -int libertas_send_specific_ssid_scan(wlan_private * priv, u8 *ssid, +int lbs_send_specific_ssid_scan(struct lbs_private *priv, u8 *ssid, u8 ssid_len, u8 clear_ssid); -int libertas_cmd_80211_scan(wlan_private * priv, +int lbs_cmd_80211_scan(struct lbs_private *priv, struct cmd_ds_command *cmd, void *pdata_buf); -int libertas_ret_80211_scan(wlan_private * priv, +int lbs_ret_80211_scan(struct lbs_private *priv, struct cmd_ds_command *resp); -int wlan_scan_networks(wlan_private * priv, - const struct wlan_ioctl_user_scan_cfg * puserscanin, +int lbs_scan_networks(struct lbs_private *priv, + const struct lbs_ioctl_user_scan_cfg *puserscanin, int full_scan); struct ifreq; @@ -205,11 +197,11 @@ struct ifreq; struct iw_point; struct iw_param; struct iw_request_info; -int libertas_get_scan(struct net_device *dev, struct iw_request_info *info, +int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra); -int libertas_set_scan(struct net_device *dev, struct iw_request_info *info, +int lbs_set_scan(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra); -void libertas_scan_worker(struct work_struct *work); +void lbs_scan_worker(struct work_struct *work); -#endif /* _WLAN_SCAN_H */ +#endif diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c index fbec06c..b423ce1 100644 --- a/drivers/net/wireless/libertas/tx.c +++ b/drivers/net/wireless/libertas/tx.c @@ -52,11 +52,11 @@ static u32 convert_radiotap_rate_to_mv(u8 rate) * @brief This function processes a single packet and sends * to IF layer * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param skb A pointer to skb which includes TX packet * @return 0 or -1 */ -static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) +static int SendSinglePacket(struct lbs_private *priv, struct sk_buff *skb) { int ret = 0; struct txpd localtxpd; @@ -86,7 +86,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) plocaltxpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); p802x_hdr = skb->data; - if (priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (priv->adapter->monitormode != LBS_MONITOR_OFF) { /* locate radiotap header */ pradiotap_hdr = (struct tx_radiotap_hdr *)skb->data; @@ -106,7 +106,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb) } /* copy destination address from 802.3 or 802.11 header */ - if (priv->adapter->monitormode != WLAN_MONITOR_OFF) + if (priv->adapter->monitormode != LBS_MONITOR_OFF) memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN); else memcpy(plocaltxpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN); @@ -144,7 +144,7 @@ done: priv->stats.tx_errors++; } - if (!ret && priv->adapter->monitormode != WLAN_MONITOR_OFF) { + if (!ret && priv->adapter->monitormode != LBS_MONITOR_OFF) { /* Keep the skb to echo it back once Tx feedback is received from FW */ skb_orphan(skb); @@ -164,9 +164,9 @@ done: } -void libertas_tx_runqueue(wlan_private *priv) +void lbs_tx_runqueue(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; int i; spin_lock(&adapter->txqueue_lock); @@ -180,9 +180,9 @@ void libertas_tx_runqueue(wlan_private *priv) spin_unlock(&adapter->txqueue_lock); } -static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb) +static void lbs_tx_queue(struct lbs_private *priv, struct sk_buff *skb) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; spin_lock(&adapter->txqueue_lock); @@ -205,10 +205,10 @@ static void wlan_tx_queue(wlan_private *priv, struct sk_buff *skb) * @brief This function checks the conditions and sends packet to IF * layer if everything is ok. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @return n/a */ -int libertas_process_tx(wlan_private * priv, struct sk_buff *skb) +int lbs_process_tx(struct lbs_private *priv, struct sk_buff *skb) { int ret = -1; @@ -223,7 +223,7 @@ int libertas_process_tx(wlan_private * priv, struct sk_buff *skb) if ((priv->adapter->psstate == PS_STATE_SLEEP) || (priv->adapter->psstate == PS_STATE_PRE_SLEEP)) { - wlan_tx_queue(priv, skb); + lbs_tx_queue(priv, skb); return ret; } @@ -239,20 +239,20 @@ done: * @brief This function sends to the host the last transmitted packet, * filling the radiotap headers with transmission information. * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @param status A 32 bit value containing transmission status. * * @returns void */ -void libertas_send_tx_feedback(wlan_private * priv) +void lbs_send_tx_feedback(struct lbs_private *priv) { - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; struct tx_radiotap_hdr *radiotap_hdr; u32 status = adapter->eventcause; int txfail; int try_count; - if (adapter->monitormode == WLAN_MONITOR_OFF || + if (adapter->monitormode == LBS_MONITOR_OFF || adapter->currenttxskb == NULL) return; @@ -270,13 +270,14 @@ void libertas_send_tx_feedback(wlan_private * priv) try_count = (status >> 16) & 0xff; radiotap_hdr->data_retries = (try_count) ? (1 + adapter->txretrycount - try_count) : 0; - libertas_upload_rx_packet(priv, adapter->currenttxskb); + lbs_upload_rx_packet(priv, adapter->currenttxskb); adapter->currenttxskb = NULL; priv->adapter->TxLockFlag = 0; - if (priv->adapter->connect_status == LIBERTAS_CONNECTED) { + + if (adapter->connect_status == LBS_CONNECTED) netif_wake_queue(priv->dev); - if (priv->mesh_dev) - netif_wake_queue(priv->mesh_dev); - } + + if (priv->mesh_dev && (adapter->mesh_connect_status == LBS_CONNECTED)) + netif_wake_queue(priv->mesh_dev); } -EXPORT_SYMBOL_GPL(libertas_send_tx_feedback); +EXPORT_SYMBOL_GPL(lbs_send_tx_feedback); diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h index a43a5f6..f0d5795 100644 --- a/drivers/net/wireless/libertas/types.h +++ b/drivers/net/wireless/libertas/types.h @@ -1,8 +1,8 @@ /** * This header file contains definition for global types */ -#ifndef _WLAN_TYPES_ -#define _WLAN_TYPES_ +#ifndef _LBS_TYPES_H_ +#define _LBS_TYPES_H_ #include #include @@ -201,22 +201,11 @@ struct mrvlietypes_powercapability { s8 maxpower; } __attribute__ ((packed)); -struct mrvlietypes_rssithreshold { +/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */ +struct mrvlietypes_thresholds { struct mrvlietypesheader header; - u8 rssivalue; - u8 rssifreq; -} __attribute__ ((packed)); - -struct mrvlietypes_snrthreshold { - struct mrvlietypesheader header; - u8 snrvalue; - u8 snrfreq; -} __attribute__ ((packed)); - -struct mrvlietypes_failurecount { - struct mrvlietypesheader header; - u8 failvalue; - u8 Failfreq; + u8 value; + u8 freq; } __attribute__ ((packed)); struct mrvlietypes_beaconsmissed { @@ -250,4 +239,4 @@ struct mrvlietypes_ledgpio { struct led_pin ledpin[1]; } __attribute__ ((packed)); -#endif /* _WLAN_TYPES_ */ +#endif diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 395b788..b8c93c0 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -21,24 +21,40 @@ #include "assoc.h" +static inline void lbs_postpone_association_work(struct lbs_private *priv) +{ + if (priv->adapter->surpriseremoved) + return; + cancel_delayed_work(&priv->assoc_work); + queue_delayed_work(priv->work_thread, &priv->assoc_work, HZ / 2); +} + +static inline void lbs_cancel_association_work(struct lbs_private *priv) +{ + cancel_delayed_work(&priv->assoc_work); + kfree(priv->adapter->pending_assoc_req); + priv->adapter->pending_assoc_req = NULL; +} + + /** * @brief Find the channel frequency power info with specific channel * - * @param adapter A pointer to wlan_adapter structure + * @param adapter A pointer to struct lbs_adapter structure * @param band it can be BAND_A, BAND_G or BAND_B * @param channel the channel for looking * @return A pointer to struct chan_freq_power structure or NULL if not find. */ -struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * adapter, - u8 band, u16 channel) +struct chan_freq_power *lbs_find_cfp_by_band_and_channel( + struct lbs_adapter *adapter, + u8 band, + u16 channel) { struct chan_freq_power *cfp = NULL; struct region_channel *rc; - int count = sizeof(adapter->region_channel) / - sizeof(adapter->region_channel[0]); int i, j; - for (j = 0; !cfp && (j < count); j++) { + for (j = 0; !cfp && (j < ARRAY_SIZE(adapter->region_channel)); j++) { rc = &adapter->region_channel[j]; if (adapter->enable11d) @@ -56,7 +72,7 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada } if (!cfp && channel) - lbs_deb_wext("libertas_find_cfp_by_band_and_channel: can't find " + lbs_deb_wext("lbs_find_cfp_by_band_and_channel: can't find " "cfp by band %d / channel %d\n", band, channel); return cfp; @@ -65,21 +81,21 @@ struct chan_freq_power *libertas_find_cfp_by_band_and_channel(wlan_adapter * ada /** * @brief Find the channel frequency power info with specific frequency * - * @param adapter A pointer to wlan_adapter structure + * @param adapter A pointer to struct lbs_adapter structure * @param band it can be BAND_A, BAND_G or BAND_B * @param freq the frequency for looking * @return A pointer to struct chan_freq_power structure or NULL if not find. */ -static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter, - u8 band, u32 freq) +static struct chan_freq_power *find_cfp_by_band_and_freq( + struct lbs_adapter *adapter, + u8 band, + u32 freq) { struct chan_freq_power *cfp = NULL; struct region_channel *rc; - int count = sizeof(adapter->region_channel) / - sizeof(adapter->region_channel[0]); int i, j; - for (j = 0; !cfp && (j < count); j++) { + for (j = 0; !cfp && (j < ARRAY_SIZE(adapter->region_channel)); j++) { rc = &adapter->region_channel[j]; if (adapter->enable11d) @@ -107,14 +123,14 @@ static struct chan_freq_power *find_cfp_by_band_and_freq(wlan_adapter * adapter, /** * @brief Set Radio On/OFF * - * @param priv A pointer to wlan_private structure + * @param priv A pointer to struct lbs_private structure * @option Radio Option * @return 0 --success, otherwise fail */ -static int wlan_radio_ioctl(wlan_private * priv, u8 option) +static int lbs_radio_ioctl(struct lbs_private *priv, u8 option) { int ret = 0; - wlan_adapter *adapter = priv->adapter; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -122,7 +138,7 @@ static int wlan_radio_ioctl(wlan_private * priv, u8 option) lbs_deb_wext("switching radio %s\n", option ? "on" : "off"); adapter->radioon = option; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RADIO_CONTROL, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -135,22 +151,23 @@ static int wlan_radio_ioctl(wlan_private * priv, u8 option) /** * @brief Copy active data rates based on adapter mode and status * - * @param adapter A pointer to wlan_adapter structure + * @param adapter A pointer to struct lbs_adapter structure * @param rate The buf to return the active rates */ -static void copy_active_data_rates(wlan_adapter * adapter, u8 * rates) +static void copy_active_data_rates(struct lbs_adapter *adapter, u8 *rates) { lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->connect_status != LIBERTAS_CONNECTED) - memcpy(rates, libertas_bg_rates, MAX_RATES); + if ((adapter->connect_status != LBS_CONNECTED) && + (adapter->mesh_connect_status != LBS_CONNECTED)) + memcpy(rates, lbs_bg_rates, MAX_RATES); else memcpy(rates, adapter->curbssparams.rates, MAX_RATES); lbs_deb_leave(LBS_DEB_WEXT); } -static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_name(struct net_device *dev, struct iw_request_info *info, char *cwrq, char *extra) { @@ -163,16 +180,16 @@ static int wlan_get_name(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct chan_freq_power *cfp; lbs_deb_enter(LBS_DEB_WEXT); - cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, + cfp = lbs_find_cfp_by_band_and_channel(adapter, 0, adapter->curbssparams.channel); if (!cfp) { @@ -190,15 +207,15 @@ static int wlan_get_freq(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_wap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *awrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->connect_status == LBS_CONNECTED) { memcpy(awrq->sa_data, adapter->curbssparams.bssid, ETH_ALEN); } else { memset(awrq->sa_data, 0, ETH_ALEN); @@ -209,11 +226,11 @@ static int wlan_get_wap(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -234,11 +251,11 @@ static int wlan_set_nick(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -255,14 +272,14 @@ static int wlan_get_nick(struct net_device *dev, struct iw_request_info *info, static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); /* Use nickname to indicate that mesh is on */ - if (adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->mesh_connect_status == LBS_CONNECTED) { strncpy(extra, "Mesh", 12); extra[12] = '\0'; dwrq->length = strlen(extra); @@ -277,12 +294,12 @@ static int mesh_get_nick(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_rts(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; u32 rthr = vwrq->value; lbs_deb_enter(LBS_DEB_WEXT); @@ -295,7 +312,7 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, adapter->rtsthsd = rthr; } - ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, OID_802_11_RTS_THRESHOLD, &rthr); @@ -303,17 +320,17 @@ static int wlan_set_rts(struct net_device *dev, struct iw_request_info *info, return ret; } -static int wlan_get_rts(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_rts(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); adapter->rtsthsd = 0; - ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, OID_802_11_RTS_THRESHOLD, NULL); if (ret) @@ -329,13 +346,13 @@ out: return ret; } -static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_frag(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; u32 fthr = vwrq->value; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -348,7 +365,7 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, adapter->fragthsd = fthr; } - ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, OID_802_11_FRAGMENTATION_THRESHOLD, &fthr); @@ -356,17 +373,17 @@ static int wlan_set_frag(struct net_device *dev, struct iw_request_info *info, return ret; } -static int wlan_get_frag(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_frag(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); adapter->fragthsd = 0; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, OID_802_11_FRAGMENTATION_THRESHOLD, NULL); @@ -383,11 +400,11 @@ out: return ret; } -static int wlan_get_mode(struct net_device *dev, +static int lbs_get_mode(struct net_device *dev, struct iw_request_info *info, u32 * uwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -409,17 +426,17 @@ static int mesh_wlan_get_mode(struct net_device *dev, return 0; } -static int wlan_get_txpow(struct net_device *dev, +static int lbs_get_txpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_TX_POWER, CMD_ACT_TX_POWER_OPT_GET, CMD_OPTION_WAITFORRSP, 0, NULL); @@ -442,12 +459,12 @@ out: return ret; } -static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_retry(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -462,7 +479,7 @@ static int wlan_set_retry(struct net_device *dev, struct iw_request_info *info, /* Adding 1 to convert retry count to try count */ adapter->txretrycount = vwrq->value + 1; - ret = libertas_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, OID_802_11_TX_RETRYCOUNT, NULL); @@ -478,17 +495,17 @@ out: return ret; } -static int wlan_get_retry(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_retry(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; lbs_deb_enter(LBS_DEB_WEXT); adapter->txretrycount = 0; - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_SNMP_MIB, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, OID_802_11_TX_RETRYCOUNT, NULL); @@ -546,12 +563,12 @@ static inline void sort_channels(struct iw_freq *freq, int num) * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */ -static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_range(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int i, j; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct iw_range *range = (struct iw_range *)extra; struct chan_freq_power *cfp; u8 rates[MAX_RATES + 1]; @@ -577,7 +594,8 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, range->num_frequency = 0; if (priv->adapter->enable11d && - adapter->connect_status == LIBERTAS_CONNECTED) { + (adapter->connect_status == LBS_CONNECTED || + adapter->mesh_connect_status == LBS_CONNECTED)) { u8 chan_no; u8 band; @@ -598,7 +616,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, lbs_deb_wext("chan_no %d\n", chan_no); range->freq[range->num_frequency].i = (long)chan_no; range->freq[range->num_frequency].m = - (long)libertas_chan_2_freq(chan_no, band) * 100000; + (long)lbs_chan_2_freq(chan_no, band) * 100000; range->freq[range->num_frequency].e = 1; range->num_frequency++; } @@ -606,8 +624,7 @@ static int wlan_get_range(struct net_device *dev, struct iw_request_info *info, } if (!flag) { for (j = 0; (range->num_frequency < IW_MAX_FREQUENCIES) - && (j < sizeof(adapter->region_channel) - / sizeof(adapter->region_channel[0])); j++) { + && (j < ARRAY_SIZE(adapter->region_channel)); j++) { cfp = adapter->region_channel[j].CFP; for (i = 0; (range->num_frequency < IW_MAX_FREQUENCIES) && adapter->region_channel[j].valid @@ -724,11 +741,11 @@ out: return 0; } -static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -737,9 +754,9 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, */ if (vwrq->disabled) { - adapter->psmode = WLAN802_11POWERMODECAM; + adapter->psmode = LBS802_11POWERMODECAM; if (adapter->psstate != PS_STATE_FULL_POWER) { - libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); + lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); } return 0; @@ -754,33 +771,33 @@ static int wlan_set_power(struct net_device *dev, struct iw_request_info *info, return -EINVAL; } - if (adapter->psmode != WLAN802_11POWERMODECAM) { + if (adapter->psmode != LBS802_11POWERMODECAM) { return 0; } - adapter->psmode = WLAN802_11POWERMODEMAX_PSP; + adapter->psmode = LBS802_11POWERMODEMAX_PSP; - if (adapter->connect_status == LIBERTAS_CONNECTED) { - libertas_ps_sleep(priv, CMD_OPTION_WAITFORRSP); + if (adapter->connect_status == LBS_CONNECTED) { + lbs_ps_sleep(priv, CMD_OPTION_WAITFORRSP); } lbs_deb_leave(LBS_DEB_WEXT); return 0; } -static int wlan_get_power(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_power(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int mode; lbs_deb_enter(LBS_DEB_WEXT); mode = adapter->psmode; - if ((vwrq->disabled = (mode == WLAN802_11POWERMODECAM)) - || adapter->connect_status == LIBERTAS_DISCONNECTED) + if ((vwrq->disabled = (mode == LBS802_11POWERMODECAM)) + || adapter->connect_status == LBS_DISCONNECTED) { goto out; } @@ -792,7 +809,7 @@ out: return 0; } -static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) +static struct iw_statistics *lbs_get_wireless_stats(struct net_device *dev) { enum { POOR = 30, @@ -802,8 +819,8 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) EXCELLENT = 95, PERFECT = 100 }; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; u32 rssi_qual; u32 tx_qual; u32 quality = 0; @@ -816,7 +833,8 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) priv->wstats.status = adapter->mode; /* If we're not associated, all quality values are meaningless */ - if (adapter->connect_status != LIBERTAS_CONNECTED) + if ((adapter->connect_status != LBS_CONNECTED) && + (adapter->mesh_connect_status != LBS_CONNECTED)) goto out; /* Quality by RSSI */ @@ -879,9 +897,9 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) stats_valid = 1; /* update stats asynchronously for future calls */ - libertas_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, + lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0, 0, 0, NULL); - libertas_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, + lbs_prepare_and_send_command(priv, CMD_802_11_GET_LOG, 0, 0, 0, NULL); out: if (!stats_valid) { @@ -901,19 +919,19 @@ out: } -static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_freq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *fwrq, char *extra) { int ret = -EINVAL; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct chan_freq_power *cfp; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; @@ -938,7 +956,7 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, goto out; } - cfp = libertas_find_cfp_by_band_and_channel(adapter, 0, fwrq->m); + cfp = lbs_find_cfp_by_band_and_channel(adapter, 0, fwrq->m); if (!cfp) { goto out; } @@ -949,9 +967,9 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info, out: if (ret == 0) { set_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } else { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -959,11 +977,11 @@ out: return ret; } -static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; u32 new_rate; u16 action; int ret = -EINVAL; @@ -995,7 +1013,7 @@ static int wlan_set_rate(struct net_device *dev, struct iw_request_info *info, adapter->auto_rate = 0; } - ret = libertas_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_DATA_RATE, action, CMD_OPTION_WAITFORRSP, 0, NULL); out: @@ -1003,15 +1021,15 @@ out: return ret; } -static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_rate(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); - if (adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->connect_status == LBS_CONNECTED) { vwrq->value = adapter->cur_rate * 500000; if (adapter->auto_rate) @@ -1028,12 +1046,12 @@ static int wlan_get_rate(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_set_mode(struct net_device *dev, +static int lbs_set_mode(struct net_device *dev, struct iw_request_info *info, u32 * uwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); @@ -1047,14 +1065,14 @@ static int wlan_set_mode(struct net_device *dev, } mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } else { assoc_req->mode = *uwrq; set_bit(ASSOC_FLAG_MODE, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); lbs_deb_wext("Switching to mode: 0x%x\n", *uwrq); } mutex_unlock(&adapter->lock); @@ -1074,12 +1092,12 @@ out: * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */ -static int wlan_get_encode(struct net_device *dev, +static int lbs_get_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, u8 * extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; lbs_deb_enter(LBS_DEB_WEXT); @@ -1160,7 +1178,7 @@ static int wlan_get_encode(struct net_device *dev, * @param set_tx_key Force set TX key (1 = yes, 0 = no) * @return 0 --success, otherwise fail */ -static int wlan_set_wep_key(struct assoc_request *assoc_req, +static int lbs_set_wep_key(struct assoc_request *assoc_req, const char *key_material, u16 key_length, u16 index, @@ -1278,20 +1296,20 @@ static void disable_wpa(struct assoc_request *assoc_req) * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */ -static int wlan_set_encode(struct net_device *dev, +static int lbs_set_encode(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; u16 is_default = 0, index = 0, set_tx_key = 0; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; @@ -1317,7 +1335,7 @@ static int wlan_set_encode(struct net_device *dev, if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default)) set_tx_key = 1; - ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); + ret = lbs_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key); if (ret) goto out; @@ -1335,9 +1353,9 @@ static int wlan_set_encode(struct net_device *dev, out: if (ret == 0) { set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } else { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1354,14 +1372,14 @@ out: * @param extra A pointer to extra data buf * @return 0 on success, otherwise failure */ -static int wlan_get_encodeext(struct net_device *dev, +static int lbs_get_encodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int ret = -EINVAL; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int index, max_key_len; @@ -1380,7 +1398,7 @@ static int wlan_get_encodeext(struct net_device *dev, index = adapter->wep_tx_keyidx; } - if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && + if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && ext->alg != IW_ENCODE_ALG_WEP) { if (index != 0 || adapter->mode != IW_MODE_INFRA) goto out; @@ -1461,14 +1479,14 @@ out: * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */ -static int wlan_set_encodeext(struct net_device *dev, +static int lbs_set_encodeext(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; int alg = ext->alg; struct assoc_request * assoc_req; @@ -1476,7 +1494,7 @@ static int wlan_set_encodeext(struct net_device *dev, lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; @@ -1503,7 +1521,7 @@ static int wlan_set_encodeext(struct net_device *dev, set_tx_key = 1; /* Copy key to driver */ - ret = wlan_set_wep_key (assoc_req, ext->key, ext->key_len, index, + ret = lbs_set_wep_key(assoc_req, ext->key, ext->key_len, index, set_tx_key); if (ret) goto out; @@ -1576,9 +1594,9 @@ static int wlan_set_encodeext(struct net_device *dev, out: if (ret == 0) { - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } else { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1587,20 +1605,20 @@ out: } -static int wlan_set_genie(struct net_device *dev, +static int lbs_set_genie(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; struct assoc_request * assoc_req; lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; @@ -1623,9 +1641,9 @@ static int wlan_set_genie(struct net_device *dev, out: if (ret == 0) { set_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } else { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1633,14 +1651,14 @@ out: return ret; } -static int wlan_get_genie(struct net_device *dev, +static int lbs_get_genie(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -1663,13 +1681,13 @@ out: } -static int wlan_set_auth(struct net_device *dev, +static int lbs_set_auth(struct net_device *dev, struct iw_request_info *info, struct iw_param *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; int ret = 0; int updated = 0; @@ -1677,7 +1695,7 @@ static int wlan_set_auth(struct net_device *dev, lbs_deb_enter(LBS_DEB_WEXT); mutex_lock(&adapter->lock); - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; goto out; @@ -1752,9 +1770,9 @@ out: if (ret == 0) { if (updated) set_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } else if (ret != -EOPNOTSUPP) { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1762,14 +1780,14 @@ out: return ret; } -static int wlan_get_auth(struct net_device *dev, +static int lbs_get_auth(struct net_device *dev, struct iw_request_info *info, struct iw_param *dwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -1802,25 +1820,25 @@ static int wlan_get_auth(struct net_device *dev, } -static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_txpow(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { int ret = 0; - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; u16 dbm; lbs_deb_enter(LBS_DEB_WEXT); if (vwrq->disabled) { - wlan_radio_ioctl(priv, RADIO_OFF); + lbs_radio_ioctl(priv, RADIO_OFF); return 0; } adapter->preamble = CMD_TYPE_AUTO_PREAMBLE; - wlan_radio_ioctl(priv, RADIO_ON); + lbs_radio_ioctl(priv, RADIO_ON); /* Userspace check in iwrange if it should use dBm or mW, * therefore this should never happen... Jean II */ @@ -1836,7 +1854,7 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, lbs_deb_wext("txpower set %d dbm\n", dbm); - ret = libertas_prepare_and_send_command(priv, + ret = lbs_prepare_and_send_command(priv, CMD_802_11_RF_TX_POWER, CMD_ACT_TX_POWER_OPT_SET_LOW, CMD_OPTION_WAITFORRSP, 0, (void *)&dbm); @@ -1845,11 +1863,11 @@ static int wlan_set_txpow(struct net_device *dev, struct iw_request_info *info, return ret; } -static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, +static int lbs_get_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; lbs_deb_enter(LBS_DEB_WEXT); @@ -1861,7 +1879,7 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, /* * Get the current SSID */ - if (adapter->connect_status == LIBERTAS_CONNECTED) { + if (adapter->connect_status == LBS_CONNECTED) { memcpy(extra, adapter->curbssparams.ssid, adapter->curbssparams.ssid_len); extra[adapter->curbssparams.ssid_len] = '\0'; @@ -1881,11 +1899,11 @@ static int wlan_get_essid(struct net_device *dev, struct iw_request_info *info, return 0; } -static int wlan_set_essid(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_essid(struct net_device *dev, struct iw_request_info *info, struct iw_point *dwrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; int ret = 0; u8 ssid[IW_ESSID_MAX_SIZE]; u8 ssid_len = 0; @@ -1921,7 +1939,7 @@ out: mutex_lock(&adapter->lock); if (ret == 0) { /* Get or create the current association request */ - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { ret = -ENOMEM; } else { @@ -1929,13 +1947,13 @@ out: memcpy(&assoc_req->ssid, &ssid, IW_ESSID_MAX_SIZE); assoc_req->ssid_len = ssid_len; set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } } /* Cancel the association request if there was an error */ if (ret != 0) { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1953,11 +1971,11 @@ out: * @param extra A pointer to extra data buf * @return 0 --success, otherwise fail */ -static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, +static int lbs_set_wap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *awrq, char *extra) { - wlan_private *priv = dev->priv; - wlan_adapter *adapter = priv->adapter; + struct lbs_private *priv = dev->priv; + struct lbs_adapter *adapter = priv->adapter; struct assoc_request * assoc_req; int ret = 0; DECLARE_MAC_BUF(mac); @@ -1972,15 +1990,15 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, mutex_lock(&adapter->lock); /* Get or create the current association request */ - assoc_req = wlan_get_association_request(adapter); + assoc_req = lbs_get_association_request(adapter); if (!assoc_req) { - wlan_cancel_association_work(priv); + lbs_cancel_association_work(priv); ret = -ENOMEM; } else { /* Copy the BSSID to the association request */ memcpy(&assoc_req->bssid, awrq->sa_data, ETH_ALEN); set_bit(ASSOC_FLAG_BSSID, &assoc_req->flags); - wlan_postpone_association_work(priv); + lbs_postpone_association_work(priv); } mutex_unlock(&adapter->lock); @@ -1988,7 +2006,7 @@ static int wlan_set_wap(struct net_device *dev, struct iw_request_info *info, return ret; } -void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen) +void lbs_get_fwversion(struct lbs_adapter *adapter, char *fwversion, int maxlen) { char fwver[32]; @@ -2014,19 +2032,19 @@ void libertas_get_fwversion(wlan_adapter * adapter, char *fwversion, int maxlen) /* * iwconfig settable callbacks */ -static const iw_handler wlan_handler[] = { +static const iw_handler lbs_handler[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) wlan_get_name, /* SIOCGIWNAME */ + (iw_handler) lbs_get_name, /* SIOCGIWNAME */ (iw_handler) NULL, /* SIOCSIWNWID */ (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) wlan_set_freq, /* SIOCSIWFREQ */ - (iw_handler) wlan_get_freq, /* SIOCGIWFREQ */ - (iw_handler) wlan_set_mode, /* SIOCSIWMODE */ - (iw_handler) wlan_get_mode, /* SIOCGIWMODE */ + (iw_handler) lbs_set_freq, /* SIOCSIWFREQ */ + (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ + (iw_handler) lbs_set_mode, /* SIOCSIWMODE */ + (iw_handler) lbs_get_mode, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ (iw_handler) NULL, /* SIOCGIWSENS */ (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) wlan_get_range, /* SIOCGIWRANGE */ + (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ (iw_handler) NULL, /* SIOCSIWPRIV */ (iw_handler) NULL, /* SIOCGIWPRIV */ (iw_handler) NULL, /* SIOCSIWSTATS */ @@ -2035,56 +2053,56 @@ static const iw_handler wlan_handler[] = { iw_handler_get_spy, /* SIOCGIWSPY */ iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ - (iw_handler) wlan_set_wap, /* SIOCSIWAP */ - (iw_handler) wlan_get_wap, /* SIOCGIWAP */ + (iw_handler) lbs_set_wap, /* SIOCSIWAP */ + (iw_handler) lbs_get_wap, /* SIOCGIWAP */ (iw_handler) NULL, /* SIOCSIWMLME */ (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ - (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */ - (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */ - (iw_handler) wlan_set_essid, /* SIOCSIWESSID */ - (iw_handler) wlan_get_essid, /* SIOCGIWESSID */ - (iw_handler) wlan_set_nick, /* SIOCSIWNICKN */ - (iw_handler) wlan_get_nick, /* SIOCGIWNICKN */ + (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ + (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ + (iw_handler) lbs_set_essid, /* SIOCSIWESSID */ + (iw_handler) lbs_get_essid, /* SIOCGIWESSID */ + (iw_handler) lbs_set_nick, /* SIOCSIWNICKN */ + (iw_handler) lbs_get_nick, /* SIOCGIWNICKN */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ - (iw_handler) wlan_set_rate, /* SIOCSIWRATE */ - (iw_handler) wlan_get_rate, /* SIOCGIWRATE */ - (iw_handler) wlan_set_rts, /* SIOCSIWRTS */ - (iw_handler) wlan_get_rts, /* SIOCGIWRTS */ - (iw_handler) wlan_set_frag, /* SIOCSIWFRAG */ - (iw_handler) wlan_get_frag, /* SIOCGIWFRAG */ - (iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */ - (iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */ - (iw_handler) wlan_set_retry, /* SIOCSIWRETRY */ - (iw_handler) wlan_get_retry, /* SIOCGIWRETRY */ - (iw_handler) wlan_set_encode, /* SIOCSIWENCODE */ - (iw_handler) wlan_get_encode, /* SIOCGIWENCODE */ - (iw_handler) wlan_set_power, /* SIOCSIWPOWER */ - (iw_handler) wlan_get_power, /* SIOCGIWPOWER */ + (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ + (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ + (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ + (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ + (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ + (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ + (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ + (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ + (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ + (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ + (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ + (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ + (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ + (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ - (iw_handler) wlan_set_genie, /* SIOCSIWGENIE */ - (iw_handler) wlan_get_genie, /* SIOCGIWGENIE */ - (iw_handler) wlan_set_auth, /* SIOCSIWAUTH */ - (iw_handler) wlan_get_auth, /* SIOCGIWAUTH */ - (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */ - (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */ + (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ + (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ + (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ + (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ + (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ + (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ (iw_handler) NULL, /* SIOCSIWPMKSA */ }; static const iw_handler mesh_wlan_handler[] = { (iw_handler) NULL, /* SIOCSIWCOMMIT */ - (iw_handler) wlan_get_name, /* SIOCGIWNAME */ + (iw_handler) lbs_get_name, /* SIOCGIWNAME */ (iw_handler) NULL, /* SIOCSIWNWID */ (iw_handler) NULL, /* SIOCGIWNWID */ - (iw_handler) wlan_set_freq, /* SIOCSIWFREQ */ - (iw_handler) wlan_get_freq, /* SIOCGIWFREQ */ + (iw_handler) lbs_set_freq, /* SIOCSIWFREQ */ + (iw_handler) lbs_get_freq, /* SIOCGIWFREQ */ (iw_handler) NULL, /* SIOCSIWMODE */ (iw_handler) mesh_wlan_get_mode, /* SIOCGIWMODE */ (iw_handler) NULL, /* SIOCSIWSENS */ (iw_handler) NULL, /* SIOCGIWSENS */ (iw_handler) NULL, /* SIOCSIWRANGE */ - (iw_handler) wlan_get_range, /* SIOCGIWRANGE */ + (iw_handler) lbs_get_range, /* SIOCGIWRANGE */ (iw_handler) NULL, /* SIOCSIWPRIV */ (iw_handler) NULL, /* SIOCGIWPRIV */ (iw_handler) NULL, /* SIOCSIWSTATS */ @@ -2097,46 +2115,46 @@ static const iw_handler mesh_wlan_handler[] = { (iw_handler) NULL, /* SIOCGIWAP */ (iw_handler) NULL, /* SIOCSIWMLME */ (iw_handler) NULL, /* SIOCGIWAPLIST - deprecated */ - (iw_handler) libertas_set_scan, /* SIOCSIWSCAN */ - (iw_handler) libertas_get_scan, /* SIOCGIWSCAN */ + (iw_handler) lbs_set_scan, /* SIOCSIWSCAN */ + (iw_handler) lbs_get_scan, /* SIOCGIWSCAN */ (iw_handler) NULL, /* SIOCSIWESSID */ (iw_handler) NULL, /* SIOCGIWESSID */ (iw_handler) NULL, /* SIOCSIWNICKN */ (iw_handler) mesh_get_nick, /* SIOCGIWNICKN */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ - (iw_handler) wlan_set_rate, /* SIOCSIWRATE */ - (iw_handler) wlan_get_rate, /* SIOCGIWRATE */ - (iw_handler) wlan_set_rts, /* SIOCSIWRTS */ - (iw_handler) wlan_get_rts, /* SIOCGIWRTS */ - (iw_handler) wlan_set_frag, /* SIOCSIWFRAG */ - (iw_handler) wlan_get_frag, /* SIOCGIWFRAG */ - (iw_handler) wlan_set_txpow, /* SIOCSIWTXPOW */ - (iw_handler) wlan_get_txpow, /* SIOCGIWTXPOW */ - (iw_handler) wlan_set_retry, /* SIOCSIWRETRY */ - (iw_handler) wlan_get_retry, /* SIOCGIWRETRY */ - (iw_handler) wlan_set_encode, /* SIOCSIWENCODE */ - (iw_handler) wlan_get_encode, /* SIOCGIWENCODE */ - (iw_handler) wlan_set_power, /* SIOCSIWPOWER */ - (iw_handler) wlan_get_power, /* SIOCGIWPOWER */ + (iw_handler) lbs_set_rate, /* SIOCSIWRATE */ + (iw_handler) lbs_get_rate, /* SIOCGIWRATE */ + (iw_handler) lbs_set_rts, /* SIOCSIWRTS */ + (iw_handler) lbs_get_rts, /* SIOCGIWRTS */ + (iw_handler) lbs_set_frag, /* SIOCSIWFRAG */ + (iw_handler) lbs_get_frag, /* SIOCGIWFRAG */ + (iw_handler) lbs_set_txpow, /* SIOCSIWTXPOW */ + (iw_handler) lbs_get_txpow, /* SIOCGIWTXPOW */ + (iw_handler) lbs_set_retry, /* SIOCSIWRETRY */ + (iw_handler) lbs_get_retry, /* SIOCGIWRETRY */ + (iw_handler) lbs_set_encode, /* SIOCSIWENCODE */ + (iw_handler) lbs_get_encode, /* SIOCGIWENCODE */ + (iw_handler) lbs_set_power, /* SIOCSIWPOWER */ + (iw_handler) lbs_get_power, /* SIOCGIWPOWER */ (iw_handler) NULL, /* -- hole -- */ (iw_handler) NULL, /* -- hole -- */ - (iw_handler) wlan_set_genie, /* SIOCSIWGENIE */ - (iw_handler) wlan_get_genie, /* SIOCGIWGENIE */ - (iw_handler) wlan_set_auth, /* SIOCSIWAUTH */ - (iw_handler) wlan_get_auth, /* SIOCGIWAUTH */ - (iw_handler) wlan_set_encodeext,/* SIOCSIWENCODEEXT */ - (iw_handler) wlan_get_encodeext,/* SIOCGIWENCODEEXT */ + (iw_handler) lbs_set_genie, /* SIOCSIWGENIE */ + (iw_handler) lbs_get_genie, /* SIOCGIWGENIE */ + (iw_handler) lbs_set_auth, /* SIOCSIWAUTH */ + (iw_handler) lbs_get_auth, /* SIOCGIWAUTH */ + (iw_handler) lbs_set_encodeext,/* SIOCSIWENCODEEXT */ + (iw_handler) lbs_get_encodeext,/* SIOCGIWENCODEEXT */ (iw_handler) NULL, /* SIOCSIWPMKSA */ }; -struct iw_handler_def libertas_handler_def = { - .num_standard = ARRAY_SIZE(wlan_handler), - .standard = (iw_handler *) wlan_handler, - .get_wireless_stats = wlan_get_wireless_stats, +struct iw_handler_def lbs_handler_def = { + .num_standard = ARRAY_SIZE(lbs_handler), + .standard = (iw_handler *) lbs_handler, + .get_wireless_stats = lbs_get_wireless_stats, }; struct iw_handler_def mesh_handler_def = { .num_standard = ARRAY_SIZE(mesh_wlan_handler), .standard = (iw_handler *) mesh_wlan_handler, - .get_wireless_stats = wlan_get_wireless_stats, + .get_wireless_stats = lbs_get_wireless_stats, }; diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h index 6aa444c..a563d9a 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h @@ -1,11 +1,11 @@ /** * This file contains definition for IOCTL call. */ -#ifndef _WLAN_WEXT_H_ -#define _WLAN_WEXT_H_ +#ifndef _LBS_WEXT_H_ +#define _LBS_WEXT_H_ -/** wlan_ioctl_regrdwr */ -struct wlan_ioctl_regrdwr { +/** lbs_ioctl_regrdwr */ +struct lbs_ioctl_regrdwr { /** Which register to access */ u16 whichreg; /** Read or Write */ @@ -15,9 +15,9 @@ struct wlan_ioctl_regrdwr { u32 value; }; -#define WLAN_MONITOR_OFF 0 +#define LBS_MONITOR_OFF 0 -extern struct iw_handler_def libertas_handler_def; +extern struct iw_handler_def lbs_handler_def; extern struct iw_handler_def mesh_handler_def; -#endif /* _WLAN_WEXT_H_ */ +#endif diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index ca6c2da..100ae33 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -270,6 +270,37 @@ static inline void set_port_type(struct orinoco_private *priv) } } +#define ORINOCO_MAX_BSS_COUNT 64 +static int orinoco_bss_data_allocate(struct orinoco_private *priv) +{ + if (priv->bss_data) + return 0; + + priv->bss_data = + kzalloc(ORINOCO_MAX_BSS_COUNT * sizeof(bss_element), GFP_KERNEL); + if (!priv->bss_data) { + printk(KERN_WARNING "Out of memory allocating beacons"); + return -ENOMEM; + } + return 0; +} + +static void orinoco_bss_data_free(struct orinoco_private *priv) +{ + kfree(priv->bss_data); + priv->bss_data = NULL; +} + +static void orinoco_bss_data_init(struct orinoco_private *priv) +{ + int i; + + INIT_LIST_HEAD(&priv->bss_free_list); + INIT_LIST_HEAD(&priv->bss_list); + for (i = 0; i < ORINOCO_MAX_BSS_COUNT; i++) + list_add_tail(&priv->bss_data[i].list, &priv->bss_free_list); +} + /********************************************************************/ /* Device methods */ /********************************************************************/ @@ -1083,6 +1114,121 @@ static void orinoco_send_wevents(struct work_struct *work) orinoco_unlock(priv, &flags); } + +static inline void orinoco_clear_scan_results(struct orinoco_private *priv, + unsigned long scan_age) +{ + bss_element *bss; + bss_element *tmp_bss; + + /* Blow away current list of scan results */ + list_for_each_entry_safe(bss, tmp_bss, &priv->bss_list, list) { + if (!scan_age || + time_after(jiffies, bss->last_scanned + scan_age)) { + list_move_tail(&bss->list, &priv->bss_free_list); + /* Don't blow away ->list, just BSS data */ + memset(bss, 0, sizeof(bss->bss)); + bss->last_scanned = 0; + } + } +} + +static int orinoco_process_scan_results(struct net_device *dev, + unsigned char *buf, + int len) +{ + struct orinoco_private *priv = netdev_priv(dev); + int offset; /* In the scan data */ + union hermes_scan_info *atom; + int atom_len; + + switch (priv->firmware_type) { + case FIRMWARE_TYPE_AGERE: + atom_len = sizeof(struct agere_scan_apinfo); + offset = 0; + break; + case FIRMWARE_TYPE_SYMBOL: + /* Lack of documentation necessitates this hack. + * Different firmwares have 68 or 76 byte long atoms. + * We try modulo first. If the length divides by both, + * we check what would be the channel in the second + * frame for a 68-byte atom. 76-byte atoms have 0 there. + * Valid channel cannot be 0. */ + if (len % 76) + atom_len = 68; + else if (len % 68) + atom_len = 76; + else if (len >= 1292 && buf[68] == 0) + atom_len = 76; + else + atom_len = 68; + offset = 0; + break; + case FIRMWARE_TYPE_INTERSIL: + offset = 4; + if (priv->has_hostscan) { + atom_len = le16_to_cpup((__le16 *)buf); + /* Sanity check for atom_len */ + if (atom_len < sizeof(struct prism2_scan_apinfo)) { + printk(KERN_ERR "%s: Invalid atom_len in scan " + "data: %d\n", dev->name, atom_len); + return -EIO; + } + } else + atom_len = offsetof(struct prism2_scan_apinfo, atim); + break; + default: + return -EOPNOTSUPP; + } + + /* Check that we got an whole number of atoms */ + if ((len - offset) % atom_len) { + printk(KERN_ERR "%s: Unexpected scan data length %d, " + "atom_len %d, offset %d\n", dev->name, len, + atom_len, offset); + return -EIO; + } + + orinoco_clear_scan_results(priv, msecs_to_jiffies(15000)); + + /* Read the entries one by one */ + for (; offset + atom_len <= len; offset += atom_len) { + int found = 0; + bss_element *bss; + + /* Get next atom */ + atom = (union hermes_scan_info *) (buf + offset); + + /* Try to update an existing bss first */ + list_for_each_entry(bss, &priv->bss_list, list) { + if (compare_ether_addr(bss->bss.a.bssid, atom->a.bssid)) + continue; + if (le16_to_cpu(bss->bss.a.essid_len) != + le16_to_cpu(atom->a.essid_len)) + continue; + if (memcmp(bss->bss.a.essid, atom->a.essid, + le16_to_cpu(atom->a.essid_len))) + continue; + bss->last_scanned = jiffies; + found = 1; + break; + } + + /* Grab a bss off the free list */ + if (!found && !list_empty(&priv->bss_free_list)) { + bss = list_entry(priv->bss_free_list.next, + bss_element, list); + list_del(priv->bss_free_list.next); + + memcpy(bss, atom, sizeof(bss->bss)); + bss->last_scanned = jiffies; + list_add_tail(&bss->list, &priv->bss_list); + } + } + + return 0; +} + static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) { struct orinoco_private *priv = netdev_priv(dev); @@ -1208,6 +1354,9 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) union iwreq_data wrqu; unsigned char *buf; + /* Scan is no longer in progress */ + priv->scan_inprogress = 0; + /* Sanity check */ if (len > 4096) { printk(KERN_WARNING "%s: Scan results too large (%d bytes)\n", @@ -1215,15 +1364,6 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) break; } - /* We are a strict producer. If the previous scan results - * have not been consumed, we just have to drop this - * frame. We can't remove the previous results ourselves, - * that would be *very* racy... Jean II */ - if (priv->scan_result != NULL) { - printk(KERN_WARNING "%s: Previous scan results not consumed, dropping info frame.\n", dev->name); - break; - } - /* Allocate buffer for results */ buf = kmalloc(len, GFP_ATOMIC); if (buf == NULL) @@ -1248,18 +1388,17 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) } #endif /* ORINOCO_DEBUG */ - /* Allow the clients to access the results */ - priv->scan_len = len; - priv->scan_result = buf; - - /* Send an empty event to user space. - * We don't send the received data on the event because - * it would require us to do complex transcoding, and - * we want to minimise the work done in the irq handler - * Use a request to extract the data - Jean II */ - wrqu.data.length = 0; - wrqu.data.flags = 0; - wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); + if (orinoco_process_scan_results(dev, buf, len) == 0) { + /* Send an empty event to user space. + * We don't send the received data on the event because + * it would require us to do complex transcoding, and + * we want to minimise the work done in the irq handler + * Use a request to extract the data - Jean II */ + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); + } + kfree(buf); } break; case HERMES_INQ_SEC_STAT_AGERE: @@ -1896,8 +2035,7 @@ static void orinoco_reset(struct work_struct *work) orinoco_unlock(priv, &flags); /* Scanning support: Cleanup of driver struct */ - kfree(priv->scan_result); - priv->scan_result = NULL; + orinoco_clear_scan_results(priv, 0); priv->scan_inprogress = 0; if (priv->hard_reset) { @@ -2412,6 +2550,10 @@ struct net_device *alloc_orinocodev(int sizeof_card, else priv->card = NULL; + if (orinoco_bss_data_allocate(priv)) + goto err_out_free; + orinoco_bss_data_init(priv); + /* Setup / override net_device fields */ dev->init = orinoco_init; dev->hard_start_xmit = orinoco_xmit; @@ -2447,13 +2589,16 @@ struct net_device *alloc_orinocodev(int sizeof_card, return dev; +err_out_free: + free_netdev(dev); + return NULL; } void free_orinocodev(struct net_device *dev) { struct orinoco_private *priv = netdev_priv(dev); - kfree(priv->scan_result); + orinoco_bss_data_free(priv); free_netdev(dev); } @@ -3841,23 +3986,10 @@ static int orinoco_ioctl_setscan(struct net_device *dev, * we access scan variables in priv is critical. * o scan_inprogress : not touched by irq handler * o scan_mode : not touched by irq handler - * o scan_result : irq is strict producer, non-irq is strict - * consumer. * o scan_len : synchronised with scan_result * Before modifying anything on those variables, please think hard ! * Jean II */ - /* If there is still some left-over scan results, get rid of it */ - if (priv->scan_result != NULL) { - /* What's likely is that a client did crash or was killed - * between triggering the scan request and reading the - * results, so we need to reset everything. - * Some clients that are too slow may suffer from that... - * Jean II */ - kfree(priv->scan_result); - priv->scan_result = NULL; - } - /* Save flags */ priv->scan_mode = srq->flags; @@ -3905,169 +4037,125 @@ static int orinoco_ioctl_setscan(struct net_device *dev, return err; } +#define MAX_CUSTOM_LEN 64 + /* Translate scan data returned from the card to a card independant * format that the Wireless Tools will understand - Jean II * Return message length or -errno for fatal errors */ -static inline int orinoco_translate_scan(struct net_device *dev, - char *buffer, - char *scan, - int scan_len) +static inline char *orinoco_translate_scan(struct net_device *dev, + char *current_ev, + char *end_buf, + union hermes_scan_info *bss, + unsigned int last_scanned) { struct orinoco_private *priv = netdev_priv(dev); - int offset; /* In the scan data */ - union hermes_scan_info *atom; - int atom_len; u16 capabilities; u16 channel; struct iw_event iwe; /* Temporary buffer */ - char * current_ev = buffer; - char * end_buf = buffer + IW_SCAN_MAX_DATA; - - switch (priv->firmware_type) { - case FIRMWARE_TYPE_AGERE: - atom_len = sizeof(struct agere_scan_apinfo); - offset = 0; - break; - case FIRMWARE_TYPE_SYMBOL: - /* Lack of documentation necessitates this hack. - * Different firmwares have 68 or 76 byte long atoms. - * We try modulo first. If the length divides by both, - * we check what would be the channel in the second - * frame for a 68-byte atom. 76-byte atoms have 0 there. - * Valid channel cannot be 0. */ - if (scan_len % 76) - atom_len = 68; - else if (scan_len % 68) - atom_len = 76; - else if (scan_len >= 1292 && scan[68] == 0) - atom_len = 76; + char *p; + char custom[MAX_CUSTOM_LEN]; + + /* First entry *MUST* be the AP MAC address */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* Other entries will be displayed in the order we give them */ + + /* Add the ESSID */ + iwe.u.data.length = le16_to_cpu(bss->a.essid_len); + if (iwe.u.data.length > 32) + iwe.u.data.length = 32; + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); + + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + capabilities = le16_to_cpu(bss->a.capabilities); + if (capabilities & 0x3) { + if (capabilities & 0x1) + iwe.u.mode = IW_MODE_MASTER; else - atom_len = 68; - offset = 0; - break; - case FIRMWARE_TYPE_INTERSIL: - offset = 4; - if (priv->has_hostscan) { - atom_len = le16_to_cpup((__le16 *)scan); - /* Sanity check for atom_len */ - if (atom_len < sizeof(struct prism2_scan_apinfo)) { - printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n", - dev->name, atom_len); - return -EIO; - } - } else - atom_len = offsetof(struct prism2_scan_apinfo, atim); - break; - default: - return -EOPNOTSUPP; - } - - /* Check that we got an whole number of atoms */ - if ((scan_len - offset) % atom_len) { - printk(KERN_ERR "%s: Unexpected scan data length %d, " - "atom_len %d, offset %d\n", dev->name, scan_len, - atom_len, offset); - return -EIO; - } - - /* Read the entries one by one */ - for (; offset + atom_len <= scan_len; offset += atom_len) { - /* Get next atom */ - atom = (union hermes_scan_info *) (scan + offset); - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN); - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); - - /* Other entries will be displayed in the order we give them */ - - /* Add the ESSID */ - iwe.u.data.length = le16_to_cpu(atom->a.essid_len); - if (iwe.u.data.length > 32) - iwe.u.data.length = 32; - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid); - - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - capabilities = le16_to_cpu(atom->a.capabilities); - if (capabilities & 0x3) { - if (capabilities & 0x1) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); - } - - channel = atom->s.channel; - if ( (channel >= 1) && (channel <= NUM_CHANNELS) ) { - /* Add frequency */ - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = channel_frequency[channel-1] * 100000; - iwe.u.freq.e = 1; - current_ev = iwe_stream_add_event(current_ev, end_buf, - &iwe, IW_EV_FREQ_LEN); - } + iwe.u.mode = IW_MODE_ADHOC; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + } + + channel = bss->s.channel; + if ((channel >= 1) && (channel <= NUM_CHANNELS)) { + /* Add frequency */ + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = channel_frequency[channel-1] * 100000; + iwe.u.freq.e = 1; + current_ev = iwe_stream_add_event(current_ev, end_buf, + &iwe, IW_EV_FREQ_LEN); + } + + /* Add quality statistics */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.updated = 0x10; /* no link quality */ + iwe.u.qual.level = (__u8) le16_to_cpu(bss->a.level) - 0x95; + iwe.u.qual.noise = (__u8) le16_to_cpu(bss->a.noise) - 0x95; + /* Wireless tools prior to 27.pre22 will show link quality + * anyway, so we provide a reasonable value. */ + if (iwe.u.qual.level > iwe.u.qual.noise) + iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; + else + iwe.u.qual.qual = 0; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); - /* Add quality statistics */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.updated = 0x10; /* no link quality */ - iwe.u.qual.level = (__u8) le16_to_cpu(atom->a.level) - 0x95; - iwe.u.qual.noise = (__u8) le16_to_cpu(atom->a.noise) - 0x95; - /* Wireless tools prior to 27.pre22 will show link quality - * anyway, so we provide a reasonable value. */ - if (iwe.u.qual.level > iwe.u.qual.noise) - iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; - else - iwe.u.qual.qual = 0; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (capabilities & 0x10) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); + + /* Add EXTRA: Age to display seconds since last beacon/probe response + * for given network. */ + iwe.cmd = IWEVCUSTOM; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + " Last beacon: %dms ago", + jiffies_to_msecs(jiffies - last_scanned)); + iwe.u.data.length = p - custom; + if (iwe.u.data.length) + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom); + + /* Bit rate is not available in Lucent/Agere firmwares */ + if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { + char *current_val = current_ev + IW_EV_LCP_LEN; + int i; + int step; - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (capabilities & 0x10) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) + step = 2; else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid); - - /* Bit rate is not available in Lucent/Agere firmwares */ - if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { - char * current_val = current_ev + IW_EV_LCP_LEN; - int i; - int step; - - if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) - step = 2; - else - step = 1; - - iwe.cmd = SIOCGIWRATE; - /* Those two flags are ignored... */ - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - /* Max 10 values */ - for (i = 0; i < 10; i += step) { - /* NULL terminated */ - if (atom->p.rates[i] == 0x0) - break; - /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000); - current_val = iwe_stream_add_value(current_ev, current_val, - end_buf, &iwe, - IW_EV_PARAM_LEN); - } - /* Check if we added any event */ - if ((current_val - current_ev) > IW_EV_LCP_LEN) - current_ev = current_val; + step = 1; + + iwe.cmd = SIOCGIWRATE; + /* Those two flags are ignored... */ + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + /* Max 10 values */ + for (i = 0; i < 10; i += step) { + /* NULL terminated */ + if (bss->p.rates[i] == 0x0) + break; + /* Bit rate given in 500 kb/s units (+ 0x80) */ + iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); + current_val = iwe_stream_add_value(current_ev, current_val, + end_buf, &iwe, + IW_EV_PARAM_LEN); } - - /* The other data in the scan result are not really - * interesting, so for now drop it - Jean II */ + /* Check if we added any event */ + if ((current_val - current_ev) > IW_EV_LCP_LEN) + current_ev = current_val; } - return current_ev - buffer; + + return current_ev; } /* Return results of a scan */ @@ -4077,68 +4165,45 @@ static int orinoco_ioctl_getscan(struct net_device *dev, char *extra) { struct orinoco_private *priv = netdev_priv(dev); + bss_element *bss; int err = 0; unsigned long flags; + char *current_ev = extra; if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - /* If no results yet, ask to try again later */ - if (priv->scan_result == NULL) { - if (priv->scan_inprogress) - /* Important note : we don't want to block the caller - * until results are ready for various reasons. - * First, managing wait queues is complex and racy. - * Second, we grab some rtnetlink lock before comming - * here (in dev_ioctl()). - * Third, we generate an Wireless Event, so the - * caller can wait itself on that - Jean II */ - err = -EAGAIN; - else - /* Client error, no scan results... - * The caller need to restart the scan. */ - err = -ENODATA; - } else { - /* We have some results to push back to user space */ - - /* Translate to WE format */ - int ret = orinoco_translate_scan(dev, extra, - priv->scan_result, - priv->scan_len); - - if (ret < 0) { - err = ret; - kfree(priv->scan_result); - priv->scan_result = NULL; - } else { - srq->length = ret; + if (priv->scan_inprogress) { + /* Important note : we don't want to block the caller + * until results are ready for various reasons. + * First, managing wait queues is complex and racy. + * Second, we grab some rtnetlink lock before comming + * here (in dev_ioctl()). + * Third, we generate an Wireless Event, so the + * caller can wait itself on that - Jean II */ + err = -EAGAIN; + goto out; + } - /* Return flags */ - srq->flags = (__u16) priv->scan_mode; + list_for_each_entry(bss, &priv->bss_list, list) { + /* Translate to WE format this entry */ + current_ev = orinoco_translate_scan(dev, current_ev, + extra + srq->length, + &bss->bss, + bss->last_scanned); - /* In any case, Scan results will be cleaned up in the - * reset function and when exiting the driver. - * The person triggering the scanning may never come to - * pick the results, so we need to do it in those places. - * Jean II */ - -#ifdef SCAN_SINGLE_READ - /* If you enable this option, only one client (the first - * one) will be able to read the result (and only one - * time). If there is multiple concurent clients that - * want to read scan results, this behavior is not - * advisable - Jean II */ - kfree(priv->scan_result); - priv->scan_result = NULL; -#endif /* SCAN_SINGLE_READ */ - /* Here, if too much time has elapsed since last scan, - * we may want to clean up scan results... - Jean II */ + /* Check if there is space for one more entry */ + if ((extra + srq->length - current_ev) <= IW_EV_ADDR_LEN) { + /* Ask user space to try again with a bigger buffer */ + err = -E2BIG; + goto out; } - - /* Scan is no longer in progress */ - priv->scan_inprogress = 0; } - + + srq->length = (current_ev - extra); + srq->flags = (__u16) priv->scan_mode; + +out: orinoco_unlock(priv, &flags); return err; } diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h index 4720fb2..c6b1858 100644 --- a/drivers/net/wireless/orinoco.h +++ b/drivers/net/wireless/orinoco.h @@ -36,6 +36,12 @@ typedef enum { FIRMWARE_TYPE_SYMBOL } fwtype_t; +typedef struct { + union hermes_scan_info bss; + unsigned long last_scanned; + struct list_head list; +} bss_element; + struct orinoco_private { void *card; /* Pointer to card dependent structure */ int (*hard_reset)(struct orinoco_private *); @@ -105,10 +111,12 @@ struct orinoco_private { int promiscuous, mc_count; /* Scanning support */ + struct list_head bss_list; + struct list_head bss_free_list; + bss_element *bss_data; + int scan_inprogress; /* Scan pending... */ u32 scan_mode; /* Type of scan done */ - char * scan_result; /* Result of previous scan */ - int scan_len; /* Lenght of result */ }; #ifdef ORINOCO_DEBUG diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c index 1437db0..8ee1453 100644 --- a/drivers/net/wireless/p54common.c +++ b/drivers/net/wireless/p54common.c @@ -374,7 +374,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) pad = entry_data->align[0]; - if (!status.control.flags & IEEE80211_TXCTL_NO_ACK) { + if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) { if (!(payload->status & 0x01)) status.flags |= IEEE80211_TX_STATUS_ACK; else diff --git a/drivers/net/wireless/p54pci.c b/drivers/net/wireless/p54pci.c index 410b543..b7a3bde 100644 --- a/drivers/net/wireless/p54pci.c +++ b/drivers/net/wireless/p54pci.c @@ -141,6 +141,7 @@ static irqreturn_t p54p_simple_interrupt(int irq, void *dev_id) static int p54p_read_eeprom(struct ieee80211_hw *dev) { struct p54p_priv *priv = dev->priv; + struct p54p_ring_control *ring_control = priv->ring_control; int err; struct p54_control_hdr *hdr; void *eeprom; @@ -164,7 +165,7 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev) goto out; } - memset(priv->ring_control, 0, sizeof(*priv->ring_control)); + memset(ring_control, 0, sizeof(*ring_control)); P54P_WRITE(ring_control_base, priv->ring_control_dma); P54P_READ(ring_control_base); udelay(10); @@ -194,14 +195,14 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev) tx_mapping = pci_map_single(priv->pdev, (void *)hdr, EEPROM_READBACK_LEN, PCI_DMA_TODEVICE); - priv->ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping); - priv->ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010); - priv->ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping); - priv->ring_control->tx_data[0].device_addr = hdr->req_id; - priv->ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN); + ring_control->rx_mgmt[0].host_addr = cpu_to_le32(rx_mapping); + ring_control->rx_mgmt[0].len = cpu_to_le16(0x2010); + ring_control->tx_data[0].host_addr = cpu_to_le32(tx_mapping); + ring_control->tx_data[0].device_addr = hdr->req_id; + ring_control->tx_data[0].len = cpu_to_le16(EEPROM_READBACK_LEN); - priv->ring_control->host_idx[2] = cpu_to_le32(1); - priv->ring_control->host_idx[1] = cpu_to_le32(1); + ring_control->host_idx[2] = cpu_to_le32(1); + ring_control->host_idx[1] = cpu_to_le32(1); wmb(); mdelay(100); @@ -215,8 +216,8 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev) pci_unmap_single(priv->pdev, rx_mapping, 0x2010, PCI_DMA_FROMDEVICE); - alen = le16_to_cpu(priv->ring_control->rx_mgmt[0].len); - if (le32_to_cpu(priv->ring_control->device_idx[2]) != 1 || + alen = le16_to_cpu(ring_control->rx_mgmt[0].len); + if (le32_to_cpu(ring_control->device_idx[2]) != 1 || alen < 0x10) { printk(KERN_ERR "%s (prism54pci): Cannot read eeprom!\n", pci_name(priv->pdev)); @@ -239,16 +240,17 @@ static int p54p_read_eeprom(struct ieee80211_hw *dev) static void p54p_refill_rx_ring(struct ieee80211_hw *dev) { struct p54p_priv *priv = dev->priv; + struct p54p_ring_control *ring_control = priv->ring_control; u32 limit, host_idx, idx; - host_idx = le32_to_cpu(priv->ring_control->host_idx[0]); + host_idx = le32_to_cpu(ring_control->host_idx[0]); limit = host_idx; - limit -= le32_to_cpu(priv->ring_control->device_idx[0]); - limit = ARRAY_SIZE(priv->ring_control->rx_data) - limit; + limit -= le32_to_cpu(ring_control->device_idx[0]); + limit = ARRAY_SIZE(ring_control->rx_data) - limit; - idx = host_idx % ARRAY_SIZE(priv->ring_control->rx_data); + idx = host_idx % ARRAY_SIZE(ring_control->rx_data); while (limit-- > 1) { - struct p54p_desc *desc = &priv->ring_control->rx_data[idx]; + struct p54p_desc *desc = &ring_control->rx_data[idx]; if (!desc->host_addr) { struct sk_buff *skb; @@ -270,17 +272,18 @@ static void p54p_refill_rx_ring(struct ieee80211_hw *dev) idx++; host_idx++; - idx %= ARRAY_SIZE(priv->ring_control->rx_data); + idx %= ARRAY_SIZE(ring_control->rx_data); } wmb(); - priv->ring_control->host_idx[0] = cpu_to_le32(host_idx); + ring_control->host_idx[0] = cpu_to_le32(host_idx); } static irqreturn_t p54p_interrupt(int irq, void *dev_id) { struct ieee80211_hw *dev = dev_id; struct p54p_priv *priv = dev->priv; + struct p54p_ring_control *ring_control = priv->ring_control; __le32 reg; spin_lock(&priv->lock); @@ -298,12 +301,12 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) struct p54p_desc *desc; u32 idx, i; i = priv->tx_idx; - i %= ARRAY_SIZE(priv->ring_control->tx_data); - priv->tx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[1]); - idx %= ARRAY_SIZE(priv->ring_control->tx_data); + i %= ARRAY_SIZE(ring_control->tx_data); + priv->tx_idx = idx = le32_to_cpu(ring_control->device_idx[1]); + idx %= ARRAY_SIZE(ring_control->tx_data); while (i != idx) { - desc = &priv->ring_control->tx_data[i]; + desc = &ring_control->tx_data[i]; if (priv->tx_buf[i]) { kfree(priv->tx_buf[i]); priv->tx_buf[i] = NULL; @@ -318,17 +321,17 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) desc->flags = 0; i++; - i %= ARRAY_SIZE(priv->ring_control->tx_data); + i %= ARRAY_SIZE(ring_control->tx_data); } i = priv->rx_idx; - i %= ARRAY_SIZE(priv->ring_control->rx_data); - priv->rx_idx = idx = le32_to_cpu(priv->ring_control->device_idx[0]); - idx %= ARRAY_SIZE(priv->ring_control->rx_data); + i %= ARRAY_SIZE(ring_control->rx_data); + priv->rx_idx = idx = le32_to_cpu(ring_control->device_idx[0]); + idx %= ARRAY_SIZE(ring_control->rx_data); while (i != idx) { u16 len; struct sk_buff *skb; - desc = &priv->ring_control->rx_data[i]; + desc = &ring_control->rx_data[i]; len = le16_to_cpu(desc->len); skb = priv->rx_buf[i]; @@ -347,7 +350,7 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) } i++; - i %= ARRAY_SIZE(priv->ring_control->rx_data); + i %= ARRAY_SIZE(ring_control->rx_data); } p54p_refill_rx_ring(dev); @@ -366,6 +369,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, size_t len, int free_on_tx) { struct p54p_priv *priv = dev->priv; + struct p54p_ring_control *ring_control = priv->ring_control; unsigned long flags; struct p54p_desc *desc; dma_addr_t mapping; @@ -373,19 +377,19 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, spin_lock_irqsave(&priv->lock, flags); - device_idx = le32_to_cpu(priv->ring_control->device_idx[1]); - idx = le32_to_cpu(priv->ring_control->host_idx[1]); - i = idx % ARRAY_SIZE(priv->ring_control->tx_data); + device_idx = le32_to_cpu(ring_control->device_idx[1]); + idx = le32_to_cpu(ring_control->host_idx[1]); + i = idx % ARRAY_SIZE(ring_control->tx_data); mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE); - desc = &priv->ring_control->tx_data[i]; + desc = &ring_control->tx_data[i]; desc->host_addr = cpu_to_le32(mapping); desc->device_addr = data->req_id; desc->len = cpu_to_le16(len); desc->flags = 0; wmb(); - priv->ring_control->host_idx[1] = cpu_to_le32(idx + 1); + ring_control->host_idx[1] = cpu_to_le32(idx + 1); if (free_on_tx) priv->tx_buf[i] = data; @@ -397,7 +401,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, /* FIXME: unlikely to happen because the device usually runs out of memory before we fill the ring up, but we can make it impossible */ - if (idx - device_idx > ARRAY_SIZE(priv->ring_control->tx_data) - 2) + if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy)); } @@ -457,6 +461,7 @@ static int p54p_open(struct ieee80211_hw *dev) static void p54p_stop(struct ieee80211_hw *dev) { struct p54p_priv *priv = dev->priv; + struct p54p_ring_control *ring_control = priv->ring_control; unsigned int i; struct p54p_desc *desc; @@ -469,7 +474,7 @@ static void p54p_stop(struct ieee80211_hw *dev) P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); for (i = 0; i < ARRAY_SIZE(priv->rx_buf); i++) { - desc = &priv->ring_control->rx_data[i]; + desc = &ring_control->rx_data[i]; if (desc->host_addr) pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), MAX_RX_SIZE, PCI_DMA_FROMDEVICE); @@ -478,7 +483,7 @@ static void p54p_stop(struct ieee80211_hw *dev) } for (i = 0; i < ARRAY_SIZE(priv->tx_buf); i++) { - desc = &priv->ring_control->tx_data[i]; + desc = &ring_control->tx_data[i]; if (desc->host_addr) pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), le16_to_cpu(desc->len), PCI_DMA_TODEVICE); @@ -487,7 +492,7 @@ static void p54p_stop(struct ieee80211_hw *dev) priv->tx_buf[i] = NULL; } - memset(priv->ring_control, 0, sizeof(*priv->ring_control)); + memset(ring_control, 0, sizeof(ring_control)); } static int __devinit p54p_probe(struct pci_dev *pdev, diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 6d80ca4..b9d0073 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -1118,7 +1118,7 @@ prism54_set_encode(struct net_device *ndev, struct iw_request_info *info, mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &index); } else { - if (!dwrq->flags & IW_ENCODE_MODE) { + if (!(dwrq->flags & IW_ENCODE_MODE)) { /* we cannot do anything. Complain. */ return -EINVAL; } @@ -2610,7 +2610,7 @@ prism2_ioctl_set_encryption(struct net_device *dev, mgt_set_request(priv, DOT11_OID_DEFKEYID, 0, &index); } else { - if (!param->u.crypt.flags & IW_ENCODE_MODE) { + if (!(param->u.crypt.flags & IW_ENCODE_MODE)) { /* we cannot do anything. Complain. */ return -EINVAL; } diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 219dd65..dbb538c 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -861,7 +861,7 @@ islpci_setup(struct pci_dev *pdev) init_waitqueue_head(&priv->reset_done); /* init the queue read locks, process wait counter */ - sema_init(&priv->mgmt_sem, 1); + mutex_init(&priv->mgmt_lock); priv->mgmt_received = NULL; init_waitqueue_head(&priv->mgmt_wqueue); sema_init(&priv->stats_sem, 1); diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h index 736666d..4e0182c 100644 --- a/drivers/net/wireless/prism54/islpci_dev.h +++ b/drivers/net/wireless/prism54/islpci_dev.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "isl_38xx.h" #include "isl_oid.h" @@ -164,7 +165,7 @@ typedef struct { wait_queue_head_t reset_done; /* used by islpci_mgt_transaction */ - struct semaphore mgmt_sem; /* serialize access to mailbox and wqueue */ + struct mutex mgmt_lock; /* serialize access to mailbox and wqueue */ struct islpci_mgmtframe *mgmt_received; /* mbox for incoming frame */ wait_queue_head_t mgmt_wqueue; /* waitqueue for mbox */ diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index 2246f79..f7c677e 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -460,7 +460,7 @@ islpci_mgt_transaction(struct net_device *ndev, *recvframe = NULL; - if (down_interruptible(&priv->mgmt_sem)) + if (mutex_lock_interruptible(&priv->mgmt_lock)) return -ERESTARTSYS; prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE); @@ -504,7 +504,7 @@ islpci_mgt_transaction(struct net_device *ndev, /* TODO: we should reset the device here */ out: finish_wait(&priv->mgmt_wqueue, &wait); - up(&priv->mgmt_sem); + mutex_unlock(&priv->mgmt_lock); return err; } diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 31c1dd2..c9a234f 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -24,11 +24,6 @@ Supported chipsets: RT2460. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2400pci" - #include #include #include @@ -54,7 +49,7 @@ * the access attempt is considered to have failed, * and we will print an error. */ -static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev) +static u32 rt2400pci_bbp_check(struct rt2x00_dev *rt2x00dev) { u32 reg; unsigned int i; @@ -69,7 +64,7 @@ static u32 rt2400pci_bbp_check(const struct rt2x00_dev *rt2x00dev) return reg; } -static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev, +static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { u32 reg; @@ -95,7 +90,7 @@ static void rt2400pci_bbp_write(const struct rt2x00_dev *rt2x00dev, rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); } -static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev, +static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { u32 reg; @@ -132,7 +127,7 @@ static void rt2400pci_bbp_read(const struct rt2x00_dev *rt2x00dev, *value = rt2x00_get_field32(reg, BBPCSR_VALUE); } -static void rt2400pci_rf_write(const struct rt2x00_dev *rt2x00dev, +static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u32 value) { u32 reg; @@ -195,13 +190,13 @@ static void rt2400pci_eepromregister_write(struct eeprom_93cx6 *eeprom) #ifdef CONFIG_RT2X00_LIB_DEBUGFS #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) -static void rt2400pci_read_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2400pci_read_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); } -static void rt2400pci_write_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2400pci_write_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); @@ -397,7 +392,7 @@ static void rt2400pci_config_txpower(struct rt2x00_dev *rt2x00dev, int txpower) } static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, - int antenna_tx, int antenna_rx) + struct antenna_setup *ant) { u8 r1; u8 r4; @@ -408,14 +403,20 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the TX antenna. */ - switch (antenna_tx) { - case ANTENNA_SW_DIVERSITY: + switch (ant->tx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1); break; case ANTENNA_A: rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2); break; @@ -424,14 +425,20 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the RX antenna. */ - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); break; case ANTENNA_A: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); break; @@ -485,9 +492,7 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev, rt2400pci_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) - rt2400pci_config_antenna(rt2x00dev, - libconf->conf->antenna_sel_tx, - libconf->conf->antenna_sel_rx); + rt2400pci_config_antenna(rt2x00dev, &libconf->ant); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt2400pci_config_duration(rt2x00dev, libconf); } @@ -514,18 +519,10 @@ static void rt2400pci_enable_led(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); - - if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { - rt2x00_set_field32(®, LEDCSR_LINK, 1); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); - } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { - rt2x00_set_field32(®, LEDCSR_LINK, 0); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); - } else { - rt2x00_set_field32(®, LEDCSR_LINK, 1); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); - } - + rt2x00_set_field32(®, LEDCSR_LINK, + (rt2x00dev->led_mode != LED_MODE_ASUS)); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, + (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); } @@ -542,7 +539,8 @@ static void rt2400pci_disable_led(struct rt2x00_dev *rt2x00dev) /* * Link tuning */ -static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev) +static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, + struct link_qual *qual) { u32 reg; u8 bbp; @@ -551,13 +549,13 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev) * Update FCS error count from register. */ rt2x00pci_register_read(rt2x00dev, CNT0, ®); - rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); + qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); /* * Update False CCA count from register. */ rt2400pci_bbp_read(rt2x00dev, 39, &bbp); - rt2x00dev->link.false_cca = bbp; + qual->false_cca = bbp; } static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev) @@ -582,10 +580,10 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) */ rt2400pci_bbp_read(rt2x00dev, 13, ®); - if (rt2x00dev->link.false_cca > 512 && reg < 0x20) { + if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) { rt2400pci_bbp_write(rt2x00dev, 13, ++reg); rt2x00dev->link.vgc_level = reg; - } else if (rt2x00dev->link.false_cca < 100 && reg > 0x08) { + } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) { rt2400pci_bbp_write(rt2x00dev, 13, --reg); rt2x00dev->link.vgc_level = reg; } @@ -597,7 +595,7 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring = rt2x00dev->rx; - struct data_desc *rxd; + __le32 *rxd; unsigned int i; u32 word; @@ -627,7 +625,7 @@ static void rt2400pci_init_rxring(struct rt2x00_dev *rt2x00dev) static void rt2400pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); - struct data_desc *txd; + __le32 *txd; unsigned int i; u32 word; @@ -1014,37 +1012,13 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, * TX descriptor initialization */ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, struct ieee80211_tx_control *control) { u32 word; - u32 signal = 0; - u32 service = 0; - u32 length_high = 0; - u32 length_low = 0; - - /* - * The PLCP values should be treated as if they - * were BBP values. - */ - rt2x00_set_field32(&signal, BBPCSR_VALUE, desc->signal); - rt2x00_set_field32(&signal, BBPCSR_REGNUM, 5); - rt2x00_set_field32(&signal, BBPCSR_BUSY, 1); - - rt2x00_set_field32(&service, BBPCSR_VALUE, desc->service); - rt2x00_set_field32(&service, BBPCSR_REGNUM, 6); - rt2x00_set_field32(&service, BBPCSR_BUSY, 1); - - rt2x00_set_field32(&length_high, BBPCSR_VALUE, desc->length_high); - rt2x00_set_field32(&length_high, BBPCSR_REGNUM, 7); - rt2x00_set_field32(&length_high, BBPCSR_BUSY, 1); - - rt2x00_set_field32(&length_low, BBPCSR_VALUE, desc->length_low); - rt2x00_set_field32(&length_low, BBPCSR_REGNUM, 8); - rt2x00_set_field32(&length_low, BBPCSR_BUSY, 1); /* * Start writing the descriptor words. @@ -1054,13 +1028,21 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); - rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, signal); - rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, service); + rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL, desc->signal); + rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_REGNUM, 5); + rt2x00_set_field32(&word, TXD_W3_PLCP_SIGNAL_BUSY, 1); + rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE, desc->service); + rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_REGNUM, 6); + rt2x00_set_field32(&word, TXD_W3_PLCP_SERVICE_BUSY, 1); rt2x00_desc_write(txd, 3, word); rt2x00_desc_read(txd, 4, &word); - rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, length_low); - rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, length_high); + rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_LOW, desc->length_low); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_REGNUM, 8); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_LOW_BUSY, 1); + rt2x00_set_field32(&word, TXD_W4_PLCP_LENGTH_HIGH, desc->length_high); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_REGNUM, 7); + rt2x00_set_field32(&word, TXD_W3_PLCP_LENGTH_HIGH_BUSY, 1); rt2x00_desc_write(txd, 4, word); rt2x00_desc_read(txd, 0, &word); @@ -1069,7 +1051,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, - !(control->flags & IEEE80211_TXCTL_NO_ACK)); + test_bit(ENTRY_TXD_ACK, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_RTS, @@ -1099,12 +1081,12 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, } rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - if (queue == IEEE80211_TX_QUEUE_DATA0) - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA1) - rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); - else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, + (queue == IEEE80211_TX_QUEUE_DATA0)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, + (queue == IEEE80211_TX_QUEUE_DATA1)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, + (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } @@ -1114,7 +1096,7 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2400pci_fill_rxdone(struct data_entry *entry, struct rxdata_entry_desc *desc) { - struct data_desc *rxd = entry->priv; + __le32 *rxd = entry->priv; u32 word0; u32 word2; @@ -1144,7 +1126,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); struct data_entry *entry; - struct data_desc *txd; + __le32 *txd; u32 word; int tx_status; int retry; @@ -1164,26 +1146,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); - rt2x00lib_txdone(entry, tx_status, retry); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - rt2x00_set_field32(&word, TXD_W0_VALID, 0); - rt2x00_desc_write(txd, 0, word); - rt2x00_ring_index_done_inc(ring); + rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); } - - /* - * If the data ring was full before the txdone handler - * we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - entry = ring->entry; - if (!rt2x00_ring_full(ring)) - ieee80211_wake_queue(rt2x00dev->hw, - entry->tx_status.control.queue); } static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance) @@ -1315,12 +1279,23 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify default antenna configuration. */ - rt2x00dev->hw->conf.antenna_sel_tx = + rt2x00dev->default_ant.tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); - rt2x00dev->hw->conf.antenna_sel_rx = + rt2x00dev->default_ant.rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* + * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead. + * I am not 100% sure about this, but the legacy drivers do not + * indicate antenna swapping in software is required when + * diversity is enabled. + */ + if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY; + if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY; + + /* * Store led mode, for correct led behaviour. */ rt2x00dev->led_mode = @@ -1614,7 +1589,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { }; static const struct rt2x00_ops rt2400pci_ops = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .rxd_size = RXD_DESC_SIZE, .txd_size = TXD_DESC_SIZE, .eeprom_size = EEPROM_SIZE, @@ -1642,7 +1617,7 @@ MODULE_DEVICE_TABLE(pci, rt2400pci_device_table); MODULE_LICENSE("GPL"); static struct pci_driver rt2400pci_driver = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .id_table = rt2400pci_device_table, .probe = rt2x00pci_probe, .remove = __devexit_p(rt2x00pci_remove), diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index ae22501..369aac6 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h @@ -803,8 +803,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 8 * sizeof(struct data_desc) ) -#define RXD_DESC_SIZE ( 8 * sizeof(struct data_desc) ) +#define TXD_DESC_SIZE ( 8 * sizeof(__le32) ) +#define RXD_DESC_SIZE ( 8 * sizeof(__le32) ) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. @@ -839,11 +839,21 @@ /* * Word3 & 4: PLCP information - */ -#define TXD_W3_PLCP_SIGNAL FIELD32(0x0000ffff) -#define TXD_W3_PLCP_SERVICE FIELD32(0xffff0000) -#define TXD_W4_PLCP_LENGTH_LOW FIELD32(0x0000ffff) -#define TXD_W4_PLCP_LENGTH_HIGH FIELD32(0xffff0000) + * The PLCP values should be treated as if they were BBP values. + */ +#define TXD_W3_PLCP_SIGNAL FIELD32(0x000000ff) +#define TXD_W3_PLCP_SIGNAL_REGNUM FIELD32(0x00007f00) +#define TXD_W3_PLCP_SIGNAL_BUSY FIELD32(0x00008000) +#define TXD_W3_PLCP_SERVICE FIELD32(0x00ff0000) +#define TXD_W3_PLCP_SERVICE_REGNUM FIELD32(0x7f000000) +#define TXD_W3_PLCP_SERVICE_BUSY FIELD32(0x80000000) + +#define TXD_W4_PLCP_LENGTH_LOW FIELD32(0x000000ff) +#define TXD_W3_PLCP_LENGTH_LOW_REGNUM FIELD32(0x00007f00) +#define TXD_W3_PLCP_LENGTH_LOW_BUSY FIELD32(0x00008000) +#define TXD_W4_PLCP_LENGTH_HIGH FIELD32(0x00ff0000) +#define TXD_W3_PLCP_LENGTH_HIGH_REGNUM FIELD32(0x7f000000) +#define TXD_W3_PLCP_LENGTH_HIGH_BUSY FIELD32(0x80000000) /* * Word5 diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 702321c..a623454 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -24,11 +24,6 @@ Supported chipsets: RT2560. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2500pci" - #include #include #include @@ -54,7 +49,7 @@ * the access attempt is considered to have failed, * and we will print an error. */ -static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev) +static u32 rt2500pci_bbp_check(struct rt2x00_dev *rt2x00dev) { u32 reg; unsigned int i; @@ -69,7 +64,7 @@ static u32 rt2500pci_bbp_check(const struct rt2x00_dev *rt2x00dev) return reg; } -static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev, +static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { u32 reg; @@ -95,7 +90,7 @@ static void rt2500pci_bbp_write(const struct rt2x00_dev *rt2x00dev, rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); } -static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev, +static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { u32 reg; @@ -132,7 +127,7 @@ static void rt2500pci_bbp_read(const struct rt2x00_dev *rt2x00dev, *value = rt2x00_get_field32(reg, BBPCSR_VALUE); } -static void rt2500pci_rf_write(const struct rt2x00_dev *rt2x00dev, +static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u32 value) { u32 reg; @@ -195,13 +190,13 @@ static void rt2500pci_eepromregister_write(struct eeprom_93cx6 *eeprom) #ifdef CONFIG_RT2X00_LIB_DEBUGFS #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) -static void rt2500pci_read_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2500pci_read_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); } -static void rt2500pci_write_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2500pci_write_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); @@ -424,7 +419,7 @@ static void rt2500pci_config_txpower(struct rt2x00_dev *rt2x00dev, } static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, const int antenna_rx) + struct antenna_setup *ant) { u32 reg; u8 r14; @@ -437,18 +432,20 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the TX antenna. */ - switch (antenna_tx) { - case ANTENNA_SW_DIVERSITY: - case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); - rt2x00_set_field32(®, BBPCSR1_CCK, 2); - rt2x00_set_field32(®, BBPCSR1_OFDM, 2); - break; + switch (ant->tx) { case ANTENNA_A: rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0); rt2x00_set_field32(®, BBPCSR1_CCK, 0); rt2x00_set_field32(®, BBPCSR1_OFDM, 0); break; + case ANTENNA_HW_DIVERSITY: + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); rt2x00_set_field32(®, BBPCSR1_CCK, 2); @@ -459,14 +456,18 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the RX antenna. */ - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: - case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); - break; + switch (ant->rx) { case ANTENNA_A: rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); break; + case ANTENNA_HW_DIVERSITY: + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); break; @@ -541,9 +542,7 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev, rt2500pci_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) - rt2500pci_config_antenna(rt2x00dev, - libconf->conf->antenna_sel_tx, - libconf->conf->antenna_sel_rx); + rt2500pci_config_antenna(rt2x00dev, &libconf->ant); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt2500pci_config_duration(rt2x00dev, libconf); } @@ -559,18 +558,10 @@ static void rt2500pci_enable_led(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 70); rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 30); - - if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { - rt2x00_set_field32(®, LEDCSR_LINK, 1); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); - } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { - rt2x00_set_field32(®, LEDCSR_LINK, 0); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); - } else { - rt2x00_set_field32(®, LEDCSR_LINK, 1); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); - } - + rt2x00_set_field32(®, LEDCSR_LINK, + (rt2x00dev->led_mode != LED_MODE_ASUS)); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, + (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); rt2x00pci_register_write(rt2x00dev, LEDCSR, reg); } @@ -587,7 +578,8 @@ static void rt2500pci_disable_led(struct rt2x00_dev *rt2x00dev) /* * Link tuning */ -static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev) +static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, + struct link_qual *qual) { u32 reg; @@ -595,13 +587,13 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev) * Update FCS error count from register. */ rt2x00pci_register_read(rt2x00dev, CNT0, ®); - rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); + qual->rx_failed = rt2x00_get_field32(reg, CNT0_FCS_ERROR); /* * Update False CCA count from register. */ rt2x00pci_register_read(rt2x00dev, CNT3, ®); - rt2x00dev->link.false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); + qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); } static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) @@ -679,10 +671,10 @@ dynamic_cca_tune: * R17 is inside the dynamic tuning range, * start tuning the link based on the false cca counter. */ - if (rt2x00dev->link.false_cca > 512 && r17 < 0x40) { + if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) { rt2500pci_bbp_write(rt2x00dev, 17, ++r17); rt2x00dev->link.vgc_level = r17; - } else if (rt2x00dev->link.false_cca < 100 && r17 > 0x32) { + } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) { rt2500pci_bbp_write(rt2x00dev, 17, --r17); rt2x00dev->link.vgc_level = r17; } @@ -694,7 +686,7 @@ dynamic_cca_tune: static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring = rt2x00dev->rx; - struct data_desc *rxd; + __le32 *rxd; unsigned int i; u32 word; @@ -719,7 +711,7 @@ static void rt2500pci_init_rxring(struct rt2x00_dev *rt2x00dev) static void rt2500pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); - struct data_desc *txd; + __le32 *txd; unsigned int i; u32 word; @@ -1170,7 +1162,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, * TX descriptor initialization */ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, @@ -1206,7 +1198,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, - !(control->flags & IEEE80211_TXCTL_NO_ACK)); + test_bit(ENTRY_TXD_ACK, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, @@ -1239,12 +1231,12 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, } rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - if (queue == IEEE80211_TX_QUEUE_DATA0) - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA1) - rt2x00_set_field32(®, TXCSR0_KICK_TX, 1); - else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON) - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, 1); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, + (queue == IEEE80211_TX_QUEUE_DATA0)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, + (queue == IEEE80211_TX_QUEUE_DATA1)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, + (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } @@ -1254,7 +1246,7 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2500pci_fill_rxdone(struct data_entry *entry, struct rxdata_entry_desc *desc) { - struct data_desc *rxd = entry->priv; + __le32 *rxd = entry->priv; u32 word0; u32 word2; @@ -1281,7 +1273,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); struct data_entry *entry; - struct data_desc *txd; + __le32 *txd; u32 word; int tx_status; int retry; @@ -1301,26 +1293,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue) tx_status = rt2x00_get_field32(word, TXD_W0_RESULT); retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); - rt2x00lib_txdone(entry, tx_status, retry); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - rt2x00_set_field32(&word, TXD_W0_VALID, 0); - rt2x00_desc_write(txd, 0, word); - rt2x00_ring_index_done_inc(ring); + rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); } - - /* - * If the data ring was full before the txdone handler - * we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - entry = ring->entry; - if (!rt2x00_ring_full(ring)) - ieee80211_wake_queue(rt2x00dev->hw, - entry->tx_status.control.queue); } static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance) @@ -1420,9 +1394,12 @@ static int rt2500pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0); - rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0); - rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0); + rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, + ANTENNA_SW_DIVERSITY); + rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, + ANTENNA_SW_DIVERSITY); + rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, + LED_MODE_DEFAULT); rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); @@ -1481,9 +1458,9 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify default antenna configuration. */ - rt2x00dev->hw->conf.antenna_sel_tx = + rt2x00dev->default_ant.tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); - rt2x00dev->hw->conf.antenna_sel_rx = + rt2x00dev->default_ant.rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* @@ -1921,7 +1898,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { }; static const struct rt2x00_ops rt2500pci_ops = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .rxd_size = RXD_DESC_SIZE, .txd_size = TXD_DESC_SIZE, .eeprom_size = EEPROM_SIZE, @@ -1949,7 +1926,7 @@ MODULE_DEVICE_TABLE(pci, rt2500pci_device_table); MODULE_LICENSE("GPL"); static struct pci_driver rt2500pci_driver = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .id_table = rt2500pci_device_table, .probe = rt2x00pci_probe, .remove = __devexit_p(rt2x00pci_remove), diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h index d92aa56..92ba090 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/drivers/net/wireless/rt2x00/rt2500pci.h @@ -1082,8 +1082,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 11 * sizeof(struct data_desc) ) -#define RXD_DESC_SIZE ( 11 * sizeof(struct data_desc) ) +#define TXD_DESC_SIZE ( 11 * sizeof(__le32) ) +#define RXD_DESC_SIZE ( 11 * sizeof(__le32) ) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 50775f9..2ba8eda 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -24,11 +24,6 @@ Supported chipsets: RT2570. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2500usb" - #include #include #include @@ -52,8 +47,10 @@ * between each attampt. When the busy bit is still set at that time, * the access attempt is considered to have failed, * and we will print an error. + * If the usb_cache_mutex is already held then the _lock variants must + * be used instead. */ -static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u16 *value) { @@ -64,8 +61,18 @@ static inline void rt2500usb_register_read(const struct rt2x00_dev *rt2x00dev, *value = le16_to_cpu(reg); } -static inline void rt2500usb_register_multiread(const struct rt2x00_dev - *rt2x00dev, +static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 *value) +{ + __le16 reg; + rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, + USB_VENDOR_REQUEST_IN, offset, + ®, sizeof(u16), REGISTER_TIMEOUT); + *value = le16_to_cpu(reg); +} + +static inline void rt2500usb_register_multiread(struct rt2x00_dev *rt2x00dev, const unsigned int offset, void *value, const u16 length) { @@ -75,7 +82,7 @@ static inline void rt2500usb_register_multiread(const struct rt2x00_dev value, length, timeout); } -static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u16 value) { @@ -85,8 +92,17 @@ static inline void rt2500usb_register_write(const struct rt2x00_dev *rt2x00dev, ®, sizeof(u16), REGISTER_TIMEOUT); } -static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev - *rt2x00dev, +static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, + u16 value) +{ + __le16 reg = cpu_to_le16(value); + rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, + USB_VENDOR_REQUEST_OUT, offset, + ®, sizeof(u16), REGISTER_TIMEOUT); +} + +static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, const unsigned int offset, void *value, const u16 length) { @@ -96,13 +112,13 @@ static inline void rt2500usb_register_multiwrite(const struct rt2x00_dev value, length, timeout); } -static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev) +static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev) { u16 reg; unsigned int i; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2500usb_register_read(rt2x00dev, PHY_CSR8, ®); + rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, ®); if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) break; udelay(REGISTER_BUSY_DELAY); @@ -111,17 +127,20 @@ static u16 rt2500usb_bbp_check(const struct rt2x00_dev *rt2x00dev) return reg; } -static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev, +static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { u16 reg; + mutex_lock(&rt2x00dev->usb_cache_mutex); + /* * Wait until the BBP becomes ready. */ reg = rt2500usb_bbp_check(rt2x00dev); if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); return; } @@ -133,14 +152,18 @@ static void rt2500usb_bbp_write(const struct rt2x00_dev *rt2x00dev, rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); - rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); + rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); + + mutex_unlock(&rt2x00dev->usb_cache_mutex); } -static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev, +static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { u16 reg; + mutex_lock(&rt2x00dev->usb_cache_mutex); + /* * Wait until the BBP becomes ready. */ @@ -157,7 +180,7 @@ static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev, rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); - rt2500usb_register_write(rt2x00dev, PHY_CSR7, reg); + rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); /* * Wait until the BBP becomes ready. @@ -166,14 +189,17 @@ static void rt2500usb_bbp_read(const struct rt2x00_dev *rt2x00dev, if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); *value = 0xff; + mutex_unlock(&rt2x00dev->usb_cache_mutex); return; } - rt2500usb_register_read(rt2x00dev, PHY_CSR7, ®); + rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); + + mutex_unlock(&rt2x00dev->usb_cache_mutex); } -static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev, +static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u32 value) { u16 reg; @@ -182,20 +208,23 @@ static void rt2500usb_rf_write(const struct rt2x00_dev *rt2x00dev, if (!word) return; + mutex_lock(&rt2x00dev->usb_cache_mutex); + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2500usb_register_read(rt2x00dev, PHY_CSR10, ®); + rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®); if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) goto rf_write; udelay(REGISTER_BUSY_DELAY); } + mutex_unlock(&rt2x00dev->usb_cache_mutex); ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); return; rf_write: reg = 0; rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); - rt2500usb_register_write(rt2x00dev, PHY_CSR9, reg); + rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg); reg = 0; rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); @@ -203,20 +232,22 @@ rf_write: rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); - rt2500usb_register_write(rt2x00dev, PHY_CSR10, reg); + rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); rt2x00_rf_write(rt2x00dev, word, value); + + mutex_unlock(&rt2x00dev->usb_cache_mutex); } #ifdef CONFIG_RT2X00_LIB_DEBUGFS #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u16)) ) -static void rt2500usb_read_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2500usb_read_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { rt2500usb_register_read(rt2x00dev, CSR_OFFSET(word), (u16 *) data); } -static void rt2500usb_write_csr(const struct rt2x00_dev *rt2x00dev, +static void rt2500usb_write_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2500usb_register_write(rt2x00dev, CSR_OFFSET(word), data); @@ -385,7 +416,7 @@ static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev, } static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, const int antenna_rx) + struct antenna_setup *ant) { u8 r2; u8 r14; @@ -400,8 +431,7 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the TX antenna. */ - switch (antenna_tx) { - case ANTENNA_SW_DIVERSITY: + switch (ant->tx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1); rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 1); @@ -412,6 +442,13 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0); rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2); rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2); @@ -422,14 +459,20 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev, /* * Configure the RX antenna. */ - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1); break; case ANTENNA_A: rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2); break; @@ -487,9 +530,7 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev, rt2500usb_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) - rt2500usb_config_antenna(rt2x00dev, - libconf->conf->antenna_sel_tx, - libconf->conf->antenna_sel_rx); + rt2500usb_config_antenna(rt2x00dev, &libconf->ant); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt2500usb_config_duration(rt2x00dev, libconf); } @@ -507,18 +548,10 @@ static void rt2500usb_enable_led(struct rt2x00_dev *rt2x00dev) rt2500usb_register_write(rt2x00dev, MAC_CSR21, reg); rt2500usb_register_read(rt2x00dev, MAC_CSR20, ®); - - if (rt2x00dev->led_mode == LED_MODE_TXRX_ACTIVITY) { - rt2x00_set_field16(®, MAC_CSR20_LINK, 1); - rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 0); - } else if (rt2x00dev->led_mode == LED_MODE_ASUS) { - rt2x00_set_field16(®, MAC_CSR20_LINK, 0); - rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1); - } else { - rt2x00_set_field16(®, MAC_CSR20_LINK, 1); - rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, 1); - } - + rt2x00_set_field16(®, MAC_CSR20_LINK, + (rt2x00dev->led_mode != LED_MODE_ASUS)); + rt2x00_set_field16(®, MAC_CSR20_ACTIVITY, + (rt2x00dev->led_mode != LED_MODE_TXRX_ACTIVITY)); rt2500usb_register_write(rt2x00dev, MAC_CSR20, reg); } @@ -535,7 +568,8 @@ static void rt2500usb_disable_led(struct rt2x00_dev *rt2x00dev) /* * Link tuning */ -static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev) +static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, + struct link_qual *qual) { u16 reg; @@ -543,14 +577,13 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev) * Update FCS error count from register. */ rt2500usb_register_read(rt2x00dev, STA_CSR0, ®); - rt2x00dev->link.rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR); + qual->rx_failed = rt2x00_get_field16(reg, STA_CSR0_FCS_ERROR); /* * Update False CCA count from register. */ rt2500usb_register_read(rt2x00dev, STA_CSR3, ®); - rt2x00dev->link.false_cca = - rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); + qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); } static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) @@ -673,10 +706,10 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev) if (r17 > up_bound) { rt2500usb_bbp_write(rt2x00dev, 17, up_bound); rt2x00dev->link.vgc_level = up_bound; - } else if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { + } else if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { rt2500usb_bbp_write(rt2x00dev, 17, ++r17); rt2x00dev->link.vgc_level = r17; - } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { + } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { rt2500usb_bbp_write(rt2x00dev, 17, --r17); rt2x00dev->link.vgc_level = r17; } @@ -755,9 +788,11 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) { rt2500usb_register_read(rt2x00dev, PHY_CSR2, ®); - reg &= ~0x0002; + rt2x00_set_field16(®, PHY_CSR2_LNA, 0); } else { - reg = 0x3002; + reg = 0; + rt2x00_set_field16(®, PHY_CSR2_LNA, 1); + rt2x00_set_field16(®, PHY_CSR2_LNA_MODE, 3); } rt2500usb_register_write(rt2x00dev, PHY_CSR2, reg); @@ -988,7 +1023,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, * TX descriptor initialization */ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, @@ -1018,7 +1053,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, - !(control->flags & IEEE80211_TXCTL_NO_ACK)); + test_bit(ENTRY_TXD_ACK, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, @@ -1080,9 +1115,8 @@ static void rt2500usb_fill_rxdone(struct data_entry *entry, struct rxdata_entry_desc *desc) { struct urb *urb = entry->priv; - struct data_desc *rxd = (struct data_desc *)(entry->skb->data + - (urb->actual_length - - entry->ring->desc_size)); + __le32 *rxd = (__le32 *)(entry->skb->data + + (urb->actual_length - entry->ring->desc_size)); u32 word0; u32 word1; @@ -1163,9 +1197,12 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 0); - rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 0); - rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, 0); + rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, + ANTENNA_SW_DIVERSITY); + rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, + ANTENNA_SW_DIVERSITY); + rt2x00_set_field16(&word, EEPROM_ANTENNA_LED_MODE, + LED_MODE_DEFAULT); rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2522); @@ -1275,12 +1312,23 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify default antenna configuration. */ - rt2x00dev->hw->conf.antenna_sel_tx = + rt2x00dev->default_ant.tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); - rt2x00dev->hw->conf.antenna_sel_rx = + rt2x00dev->default_ant.rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* + * When the eeprom indicates SW_DIVERSITY use HW_DIVERSITY instead. + * I am not 100% sure about this, but the legacy drivers do not + * indicate antenna swapping in software is required when + * diversity is enabled. + */ + if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY; + if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) + rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY; + + /* * Store led mode, for correct led behaviour. */ rt2x00dev->led_mode = @@ -1638,8 +1686,8 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct rt2x00_dev *rt2x00dev = hw->priv; struct usb_device *usb_dev = interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); - struct data_ring *ring = - rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); + struct skb_desc *desc; + struct data_ring *ring; struct data_entry *beacon; struct data_entry *guardian; int pipe = usb_sndbulkpipe(usb_dev, 1); @@ -1651,6 +1699,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); /* * Obtain 2 entries, one for the guardian byte, @@ -1661,23 +1710,34 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, beacon = rt2x00_get_data_entry(ring); /* - * First we create the beacon. + * Add the descriptor in front of the skb. */ skb_push(skb, ring->desc_size); memset(skb->data, 0, ring->desc_size); - rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, - (struct ieee80211_hdr *)(skb->data + - ring->desc_size), - skb->len - ring->desc_size, control); + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = beacon; + + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); + /* + * 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 = rt2500usb_get_tx_data_len(rt2x00dev, skb); usb_fill_bulk_urb(beacon->priv, usb_dev, pipe, skb->data, length, rt2500usb_beacondone, beacon); - beacon->skb = skb; - /* * Second we need to create the guardian byte. * We only need a single byte, so lets recycle @@ -1737,7 +1797,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { }; static const struct rt2x00_ops rt2500usb_ops = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .rxd_size = RXD_DESC_SIZE, .txd_size = TXD_DESC_SIZE, .eeprom_size = EEPROM_SIZE, @@ -1809,7 +1869,7 @@ MODULE_DEVICE_TABLE(usb, rt2500usb_device_table); MODULE_LICENSE("GPL"); static struct usb_driver rt2500usb_driver = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .id_table = rt2500usb_device_table, .probe = rt2x00usb_probe, .disconnect = rt2x00usb_disconnect, diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b18d56e..9e04337 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h @@ -430,10 +430,21 @@ /* * MAC configuration registers. + */ + +/* * PHY_CSR2: TX MAC configuration. - * PHY_CSR3: RX MAC configuration. + * NOTE: Both register fields are complete dummy, + * documentation and legacy drivers are unclear un + * what this register means or what fields exists. */ #define PHY_CSR2 0x04c4 +#define PHY_CSR2_LNA FIELD16(0x0002) +#define PHY_CSR2_LNA_MODE FIELD16(0x3000) + +/* + * PHY_CSR3: RX MAC configuration. + */ #define PHY_CSR3 0x04c6 /* @@ -692,8 +703,8 @@ /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 5 * sizeof(struct data_desc) ) -#define RXD_DESC_SIZE ( 4 * sizeof(struct data_desc) ) +#define TXD_DESC_SIZE ( 5 * sizeof(__le32) ) +#define RXD_DESC_SIZE ( 4 * sizeof(__le32) ) /* * TX descriptor format for TX, PRIO, ATIM and Beacon Ring. diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c8f16f1..85cfdab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include @@ -40,9 +42,8 @@ /* * Module information. - * DRV_NAME should be set within the individual module source files. */ -#define DRV_VERSION "2.0.10" +#define DRV_VERSION "2.0.13" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" /* @@ -55,7 +56,7 @@ #define DEBUG_PRINTK_PROBE(__kernlvl, __lvl, __msg, __args...) \ printk(__kernlvl "%s -> %s: %s - " __msg, \ - DRV_NAME, __FUNCTION__, __lvl, ##__args) + KBUILD_MODNAME, __FUNCTION__, __lvl, ##__args) #ifdef CONFIG_RT2X00_DEBUG #define DEBUG_PRINTK(__dev, __kernlvl, __lvl, __msg, __args...) \ @@ -133,20 +134,26 @@ */ static inline int is_rts_frame(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); } static inline int is_cts_frame(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); } static inline int is_probe_resp(u16 fc) { - return !!(((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && - ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); +} + +static inline int is_beacon(u16 fc) +{ + return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)); } /* @@ -180,18 +187,17 @@ struct rf_channel { }; /* - * To optimize the quality of the link we need to store - * the quality of received frames and periodically - * optimize the link. + * Antenna setup values. */ -struct link { - /* - * Link tuner counter - * The number of times the link has been tuned - * since the radio has been switched on. - */ - u32 count; +struct antenna_setup { + enum antenna rx; + enum antenna tx; +}; +/* + * Quality statistics about the currently active link. + */ +struct link_qual { /* * Statistics required for Link tuning. * For the average RSSI value we use the "Walking average" approach. @@ -211,7 +217,6 @@ struct link { * the new values correctly allowing a effective link tuning. */ int avg_rssi; - int vgc_level; int false_cca; /* @@ -240,6 +245,72 @@ struct link { #define WEIGHT_RSSI 20 #define WEIGHT_RX 40 #define WEIGHT_TX 40 +}; + +/* + * Antenna settings about the currently active link. + */ +struct link_ant { + /* + * Antenna flags + */ + unsigned int flags; +#define ANTENNA_RX_DIVERSITY 0x00000001 +#define ANTENNA_TX_DIVERSITY 0x00000002 +#define ANTENNA_MODE_SAMPLE 0x00000004 + + /* + * Currently active TX/RX antenna setup. + * When software diversity is used, this will indicate + * which antenna is actually used at this time. + */ + struct antenna_setup active; + + /* + * RSSI information for the different antenna's. + * These statistics are used to determine when + * to switch antenna when using software diversity. + * + * rssi[0] -> Antenna A RSSI + * rssi[1] -> Antenna B RSSI + */ + int rssi_history[2]; + + /* + * Current RSSI average of the currently active antenna. + * Similar to the avg_rssi in the link_qual structure + * this value is updated by using the walking average. + */ + int rssi_ant; +}; + +/* + * To optimize the quality of the link we need to store + * the quality of received frames and periodically + * optimize the link. + */ +struct link { + /* + * Link tuner counter + * The number of times the link has been tuned + * since the radio has been switched on. + */ + u32 count; + + /* + * Quality measurement values. + */ + struct link_qual qual; + + /* + * TX/RX antenna setup. + */ + struct link_ant ant; + + /* + * Active VGC level + */ + int vgc_level; /* * Work structure for scheduling periodic link tuning. @@ -248,36 +319,47 @@ struct link { }; /* - * Clear all counters inside the link structure. - * This can be easiest achieved by memsetting everything - * except for the work structure at the end. + * Small helper macro to work with moving/walking averages. */ -static inline void rt2x00_clear_link(struct link *link) -{ - memset(link, 0x00, sizeof(*link) - sizeof(link->work)); - link->rx_percentage = 50; - link->tx_percentage = 50; -} +#define MOVING_AVERAGE(__avg, __val, __samples) \ + ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) /* - * Update the rssi using the walking average approach. + * When we lack RSSI information return something less then -80 to + * tell the driver to tune the device to maximum sensitivity. */ -static inline void rt2x00_update_link_rssi(struct link *link, int rssi) -{ - if (!link->avg_rssi) - link->avg_rssi = rssi; - else - link->avg_rssi = ((link->avg_rssi * 7) + rssi) / 8; -} +#define DEFAULT_RSSI ( -128 ) /* - * When the avg_rssi is unset or no frames have been received), - * we need to return the default value which needs to be less - * than -80 so the device will select the maximum sensitivity. + * Link quality access functions. */ static inline int rt2x00_get_link_rssi(struct link *link) { - return (link->avg_rssi && link->rx_success) ? link->avg_rssi : -128; + if (link->qual.avg_rssi && link->qual.rx_success) + return link->qual.avg_rssi; + return DEFAULT_RSSI; +} + +static inline int rt2x00_get_link_ant_rssi(struct link *link) +{ + if (link->ant.rssi_ant && link->qual.rx_success) + return link->ant.rssi_ant; + return DEFAULT_RSSI; +} + +static inline int rt2x00_get_link_ant_rssi_history(struct link *link, + enum antenna ant) +{ + if (link->ant.rssi_history[ant - ANTENNA_A]) + return link->ant.rssi_history[ant - ANTENNA_A]; + return DEFAULT_RSSI; +} + +static inline int rt2x00_update_ant_rssi(struct link *link, int rssi) +{ + int old_rssi = link->ant.rssi_history[link->ant.active.rx - ANTENNA_A]; + link->ant.rssi_history[link->ant.active.rx - ANTENNA_A] = rssi; + return old_rssi; } /* @@ -294,10 +376,8 @@ struct interface { /* * Current working type (IEEE80211_IF_TYPE_*). - * When set to INVALID_INTERFACE, no interface is configured. */ int type; -#define INVALID_INTERFACE IEEE80211_IF_TYPE_INVALID /* * MAC of the device. @@ -362,6 +442,8 @@ struct rt2x00lib_conf { struct ieee80211_conf *conf; struct rf_channel rf; + struct antenna_setup ant; + int phymode; int basic_rates; @@ -402,7 +484,8 @@ struct rt2x00lib_ops { int (*set_device_state) (struct rt2x00_dev *rt2x00dev, enum dev_state state); int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); - void (*link_stats) (struct rt2x00_dev *rt2x00dev); + void (*link_stats) (struct rt2x00_dev *rt2x00dev, + struct link_qual *qual); void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); void (*link_tuner) (struct rt2x00_dev *rt2x00dev); @@ -410,7 +493,7 @@ struct rt2x00lib_ops { * TX control handlers */ void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, @@ -545,7 +628,7 @@ struct rt2x00_dev { * required for deregistration of debugfs. */ #ifdef CONFIG_RT2X00_LIB_DEBUGFS - const struct rt2x00debug_intf *debugfs_intf; + struct rt2x00debug_intf *debugfs_intf; #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ /* @@ -566,6 +649,13 @@ struct rt2x00_dev { struct hw_mode_spec spec; /* + * This is the default TX/RX antenna setup as indicated + * by the device's EEPROM. When mac80211 sets its + * antenna value to 0 we should be using these values. + */ + struct antenna_setup default_ant; + + /* * Register pointers * csr_addr: Base register address. (PCI) * csr_cache: CSR cache for usb_control_msg. (USB) @@ -574,6 +664,18 @@ struct rt2x00_dev { void *csr_cache; /* + * Mutex to protect register accesses on USB devices. + * There are 2 reasons this is needed, one is to ensure + * use of the csr_cache (for USB devices) by one thread + * isn't corrupted by another thread trying to access it. + * The other is that access to BBP and RF registers + * require multiple BUS transactions and if another thread + * attempted to access one of those registers at the same + * time one of the writes could silently fail. + */ + struct mutex usb_cache_mutex; + + /* * Interface configuration. */ struct interface interface; @@ -694,16 +796,22 @@ struct rt2x00_dev { ring_loop(__entry, (__dev)->tx, ring_end(__dev)) /* + * Compute an array index from a pointer to an element and the base pointer. + */ +#define ARRAY_INDEX(__elem, __base) \ + ( ((char *)(__elem) - (char *)(__base)) / sizeof(*(__elem)) ) + +/* * Generic RF access. * The RF is being accessed by word index. */ -static inline void rt2x00_rf_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { *data = rt2x00dev->rf[word]; } -static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2x00dev->rf[word] = data; @@ -713,19 +821,19 @@ static inline void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev, * Generic EEPROM access. * The EEPROM is being accessed by word index. */ -static inline void *rt2x00_eeprom_addr(const struct rt2x00_dev *rt2x00dev, +static inline void *rt2x00_eeprom_addr(struct rt2x00_dev *rt2x00dev, const unsigned int word) { return (void *)&rt2x00dev->eeprom[word]; } -static inline void rt2x00_eeprom_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_eeprom_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u16 *data) { *data = le16_to_cpu(rt2x00dev->eeprom[word]); } -static inline void rt2x00_eeprom_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00_eeprom_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, u16 data) { rt2x00dev->eeprom[word] = cpu_to_le16(data); @@ -804,9 +912,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, * TX descriptor initializer */ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, + struct sk_buff *skb, struct ieee80211_tx_control *control); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 12914cf..72cfe00 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -23,11 +23,6 @@ Abstract: rt2x00 generic configuration routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include @@ -94,12 +89,44 @@ void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type) rt2x00dev->ops->lib->config_type(rt2x00dev, type, tsf_sync); } +void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, + enum antenna rx, enum antenna tx) +{ + struct rt2x00lib_conf libconf; + + libconf.ant.rx = rx; + libconf.ant.tx = tx; + + /* + * Antenna setup changes require the RX to be disabled, + * else the changes will be ignored by the device. + */ + if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); + + /* + * Write new antenna setup to device and reset the link tuner. + * The latter is required since we need to recalibrate the + * noise-sensitivity ratio for the new setup. + */ + rt2x00dev->ops->lib->config(rt2x00dev, CONFIG_UPDATE_ANTENNA, &libconf); + rt2x00lib_reset_link_tuner(rt2x00dev); + + rt2x00dev->link.ant.active.rx = libconf.ant.rx; + rt2x00dev->link.ant.active.tx = libconf.ant.tx; + + if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); +} + void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, const int force_config) { struct rt2x00lib_conf libconf; struct ieee80211_hw_mode *mode; struct ieee80211_rate *rate; + struct antenna_setup *default_ant = &rt2x00dev->default_ant; + struct antenna_setup *active_ant = &rt2x00dev->link.ant.active; int flags = 0; int short_slot_time; @@ -122,7 +149,39 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, flags |= CONFIG_UPDATE_CHANNEL; if (rt2x00dev->tx_power != conf->power_level) flags |= CONFIG_UPDATE_TXPOWER; - if (rt2x00dev->rx_status.antenna == conf->antenna_sel_rx) + + /* + * Determining changes in the antenna setups request several checks: + * antenna_sel_{r,t}x = 0 + * -> Does active_{r,t}x match default_{r,t}x + * -> Is default_{r,t}x SW_DIVERSITY + * antenna_sel_{r,t}x = 1/2 + * -> Does active_{r,t}x match antenna_sel_{r,t}x + * The reason for not updating the antenna while SW diversity + * should be used is simple: Software diversity means that + * we should switch between the antenna's based on the + * quality. This means that the current antenna is good enough + * to work with untill the link tuner decides that an antenna + * switch should be performed. + */ + if (!conf->antenna_sel_rx && + default_ant->rx != ANTENNA_SW_DIVERSITY && + default_ant->rx != active_ant->rx) + flags |= CONFIG_UPDATE_ANTENNA; + else if (conf->antenna_sel_rx && + conf->antenna_sel_rx != active_ant->rx) + flags |= CONFIG_UPDATE_ANTENNA; + else if (active_ant->rx == ANTENNA_SW_DIVERSITY) + flags |= CONFIG_UPDATE_ANTENNA; + + if (!conf->antenna_sel_tx && + default_ant->tx != ANTENNA_SW_DIVERSITY && + default_ant->tx != active_ant->tx) + flags |= CONFIG_UPDATE_ANTENNA; + else if (conf->antenna_sel_tx && + conf->antenna_sel_tx != active_ant->tx) + flags |= CONFIG_UPDATE_ANTENNA; + else if (active_ant->tx == ANTENNA_SW_DIVERSITY) flags |= CONFIG_UPDATE_ANTENNA; /* @@ -171,6 +230,22 @@ config: sizeof(libconf.rf)); } + if (flags & CONFIG_UPDATE_ANTENNA) { + if (conf->antenna_sel_rx) + libconf.ant.rx = conf->antenna_sel_rx; + else if (default_ant->rx != ANTENNA_SW_DIVERSITY) + libconf.ant.rx = default_ant->rx; + else if (active_ant->rx == ANTENNA_SW_DIVERSITY) + libconf.ant.rx = ANTENNA_B; + + if (conf->antenna_sel_tx) + libconf.ant.tx = conf->antenna_sel_tx; + else if (default_ant->tx != ANTENNA_SW_DIVERSITY) + libconf.ant.tx = default_ant->tx; + else if (active_ant->tx == ANTENNA_SW_DIVERSITY) + libconf.ant.tx = ANTENNA_B; + } + if (flags & CONFIG_UPDATE_SLOT_TIME) { short_slot_time = conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME; @@ -196,10 +271,17 @@ config: if (flags & (CONFIG_UPDATE_CHANNEL | CONFIG_UPDATE_ANTENNA)) rt2x00lib_reset_link_tuner(rt2x00dev); - rt2x00dev->curr_hwmode = libconf.phymode; - rt2x00dev->rx_status.phymode = conf->phymode; + if (flags & CONFIG_UPDATE_PHYMODE) { + rt2x00dev->curr_hwmode = libconf.phymode; + rt2x00dev->rx_status.phymode = conf->phymode; + } + rt2x00dev->rx_status.freq = conf->freq; rt2x00dev->rx_status.channel = conf->channel; rt2x00dev->tx_power = conf->power_level; - rt2x00dev->rx_status.antenna = conf->antenna_sel_rx; + + if (flags & CONFIG_UPDATE_ANTENNA) { + rt2x00dev->link.ant.active.rx = libconf.ant.rx; + rt2x00dev->link.ant.active.tx = libconf.ant.tx; + } } diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 9275d6f..e72c981 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -23,18 +23,15 @@ Abstract: rt2x00 debugfs specific routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include #include +#include #include #include "rt2x00.h" #include "rt2x00lib.h" +#include "rt2x00dump.h" #define PRINT_LINE_LEN_MAX 32 @@ -55,18 +52,22 @@ struct rt2x00debug_intf { /* * Debugfs entries for: * - driver folder - * - driver file - * - chipset file - * - device flags file - * - register offset/value files - * - eeprom offset/value files - * - bbp offset/value files - * - rf offset/value files + * - driver file + * - chipset file + * - device flags file + * - register folder + * - csr offset/value files + * - eeprom offset/value files + * - bbp offset/value files + * - rf offset/value files + * - frame dump folder + * - frame dump file */ struct dentry *driver_folder; struct dentry *driver_entry; struct dentry *chipset_entry; struct dentry *dev_flags; + struct dentry *register_folder; struct dentry *csr_off_entry; struct dentry *csr_val_entry; struct dentry *eeprom_off_entry; @@ -75,6 +76,24 @@ struct rt2x00debug_intf { struct dentry *bbp_val_entry; struct dentry *rf_off_entry; struct dentry *rf_val_entry; + struct dentry *frame_folder; + struct dentry *frame_dump_entry; + + /* + * The frame dump file only allows a single reader, + * so we need to store the current state here. + */ + unsigned long frame_dump_flags; +#define FRAME_DUMP_FILE_OPEN 1 + + /* + * We queue each frame before dumping it to the user, + * per read command we will pass a single skb structure + * so we should be prepared to queue multiple sk buffers + * before sending it to userspace. + */ + struct sk_buff_head frame_dump_skbqueue; + wait_queue_head_t frame_dump_waitqueue; /* * Driver and chipset files will use a data buffer @@ -93,6 +112,63 @@ struct rt2x00debug_intf { unsigned int offset_rf; }; +void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb) +{ + struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; + struct skb_desc *desc = get_skb_desc(skb); + struct sk_buff *skbcopy; + struct rt2x00dump_hdr *dump_hdr; + struct timeval timestamp; + unsigned int ring_index; + unsigned int entry_index; + + do_gettimeofday(×tamp); + ring_index = ARRAY_INDEX(desc->ring, rt2x00dev->rx); + entry_index = ARRAY_INDEX(desc->entry, desc->ring->entry); + + if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) + return; + + if (skb_queue_len(&intf->frame_dump_skbqueue) > 20) { + DEBUG(rt2x00dev, "txrx dump queue length exceeded.\n"); + return; + } + + skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len, + GFP_ATOMIC); + if (!skbcopy) { + DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); + return; + } + + dump_hdr = (struct rt2x00dump_hdr *)skb_put(skbcopy, sizeof(*dump_hdr)); + dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); + dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); + dump_hdr->desc_length = cpu_to_le32(desc->desc_len); + dump_hdr->data_length = cpu_to_le32(desc->data_len); + dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); + dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); + dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); + dump_hdr->type = cpu_to_le16(desc->frame_type); + dump_hdr->ring_index = ring_index; + dump_hdr->entry_index = entry_index; + dump_hdr->timestamp_sec = cpu_to_le32(timestamp.tv_sec); + dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); + + memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len); + memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len); + + skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); + wake_up_interruptible(&intf->frame_dump_waitqueue); + + /* + * Verify that the file has not been closed while we were working. + */ + if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) + skb_queue_purge(&intf->frame_dump_skbqueue); +} + static int rt2x00debug_file_open(struct inode *inode, struct file *file) { struct rt2x00debug_intf *intf = inode->i_private; @@ -114,13 +190,96 @@ static int rt2x00debug_file_release(struct inode *inode, struct file *file) return 0; } +static int rt2x00debug_open_ring_dump(struct inode *inode, struct file *file) +{ + struct rt2x00debug_intf *intf = inode->i_private; + int retval; + + retval = rt2x00debug_file_open(inode, file); + if (retval) + return retval; + + if (test_and_set_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) { + rt2x00debug_file_release(inode, file); + return -EBUSY; + } + + return 0; +} + +static int rt2x00debug_release_ring_dump(struct inode *inode, struct file *file) +{ + struct rt2x00debug_intf *intf = inode->i_private; + + skb_queue_purge(&intf->frame_dump_skbqueue); + + clear_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags); + + return rt2x00debug_file_release(inode, file); +} + +static ssize_t rt2x00debug_read_ring_dump(struct file *file, + char __user *buf, + size_t length, + loff_t *offset) +{ + struct rt2x00debug_intf *intf = file->private_data; + struct sk_buff *skb; + size_t status; + int retval; + + if (file->f_flags & O_NONBLOCK) + return -EAGAIN; + + retval = + wait_event_interruptible(intf->frame_dump_waitqueue, + (skb = + skb_dequeue(&intf->frame_dump_skbqueue))); + if (retval) + return retval; + + status = min((size_t)skb->len, length); + if (copy_to_user(buf, skb->data, status)) { + status = -EFAULT; + goto exit; + } + + *offset += status; + +exit: + kfree_skb(skb); + + return status; +} + +static unsigned int rt2x00debug_poll_ring_dump(struct file *file, + poll_table *wait) +{ + struct rt2x00debug_intf *intf = file->private_data; + + poll_wait(file, &intf->frame_dump_waitqueue, wait); + + if (!skb_queue_empty(&intf->frame_dump_skbqueue)) + return POLLOUT | POLLWRNORM; + + return 0; +} + +static const struct file_operations rt2x00debug_fop_ring_dump = { + .owner = THIS_MODULE, + .read = rt2x00debug_read_ring_dump, + .poll = rt2x00debug_poll_ring_dump, + .open = rt2x00debug_open_ring_dump, + .release = rt2x00debug_release_ring_dump, +}; + #define RT2X00DEBUGFS_OPS_READ(__name, __format, __type) \ static ssize_t rt2x00debug_read_##__name(struct file *file, \ char __user *buf, \ size_t length, \ loff_t *offset) \ { \ - struct rt2x00debug_intf *intf = file->private_data; \ + struct rt2x00debug_intf *intf = file->private_data; \ const struct rt2x00debug *debug = intf->debug; \ char line[16]; \ size_t size; \ @@ -150,7 +309,7 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ size_t length, \ loff_t *offset) \ { \ - struct rt2x00debug_intf *intf = file->private_data; \ + struct rt2x00debug_intf *intf = file->private_data; \ const struct rt2x00debug *debug = intf->debug; \ char line[16]; \ size_t size; \ @@ -254,16 +413,21 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name, const struct rt2x00debug *debug = intf->debug; char *data; - data = kzalloc(4 * PRINT_LINE_LEN_MAX, GFP_KERNEL); + data = kzalloc(8 * PRINT_LINE_LEN_MAX, GFP_KERNEL); if (!data) return NULL; - blob->data = data; + data += sprintf(data, "rt chip: %04x\n", intf->rt2x00dev->chip.rt); + data += sprintf(data, "rf chip: %04x\n", intf->rt2x00dev->chip.rf); + data += sprintf(data, "revision:%08x\n", intf->rt2x00dev->chip.rev); + data += sprintf(data, "\n"); data += sprintf(data, "csr length: %d\n", debug->csr.word_count); data += sprintf(data, "eeprom length: %d\n", debug->eeprom.word_count); data += sprintf(data, "bbp length: %d\n", debug->bbp.word_count); data += sprintf(data, "rf length: %d\n", debug->rf.word_count); - blob->size = strlen(blob->data); + + blob->data = data; + blob->size = strlen(data); return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob); } @@ -306,12 +470,17 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) if (IS_ERR(intf->dev_flags)) goto exit; -#define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name) \ + intf->register_folder = + debugfs_create_dir("register", intf->driver_folder); + if (IS_ERR(intf->register_folder)) + goto exit; + +#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ ({ \ (__intf)->__name##_off_entry = \ debugfs_create_u32(__stringify(__name) "_offset", \ S_IRUGO | S_IWUSR, \ - (__intf)->driver_folder, \ + (__intf)->register_folder, \ &(__intf)->offset_##__name); \ if (IS_ERR((__intf)->__name##_off_entry)) \ goto exit; \ @@ -319,18 +488,32 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) (__intf)->__name##_val_entry = \ debugfs_create_file(__stringify(__name) "_value", \ S_IRUGO | S_IWUSR, \ - (__intf)->driver_folder, \ + (__intf)->register_folder, \ (__intf), &rt2x00debug_fop_##__name);\ if (IS_ERR((__intf)->__name##_val_entry)) \ goto exit; \ }) - RT2X00DEBUGFS_CREATE_ENTRY(intf, csr); - RT2X00DEBUGFS_CREATE_ENTRY(intf, eeprom); - RT2X00DEBUGFS_CREATE_ENTRY(intf, bbp); - RT2X00DEBUGFS_CREATE_ENTRY(intf, rf); + RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr); + RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom); + RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp); + RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf); -#undef RT2X00DEBUGFS_CREATE_ENTRY +#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY + + intf->frame_folder = + debugfs_create_dir("frame", intf->driver_folder); + if (IS_ERR(intf->frame_folder)) + goto exit; + + intf->frame_dump_entry = + debugfs_create_file("dump", S_IRUGO, intf->frame_folder, + intf, &rt2x00debug_fop_ring_dump); + if (IS_ERR(intf->frame_dump_entry)) + goto exit; + + skb_queue_head_init(&intf->frame_dump_skbqueue); + init_waitqueue_head(&intf->frame_dump_waitqueue); return; @@ -343,11 +526,15 @@ exit: void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) { - const struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; + struct rt2x00debug_intf *intf = rt2x00dev->debugfs_intf; if (unlikely(!intf)) return; + skb_queue_purge(&intf->frame_dump_skbqueue); + + debugfs_remove(intf->frame_dump_entry); + debugfs_remove(intf->frame_folder); debugfs_remove(intf->rf_val_entry); debugfs_remove(intf->rf_off_entry); debugfs_remove(intf->bbp_val_entry); @@ -356,6 +543,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) debugfs_remove(intf->eeprom_off_entry); debugfs_remove(intf->csr_val_entry); debugfs_remove(intf->csr_off_entry); + debugfs_remove(intf->register_folder); debugfs_remove(intf->dev_flags); debugfs_remove(intf->chipset_entry); debugfs_remove(intf->driver_entry); diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h index 860e8fa..d37efbd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.h +++ b/drivers/net/wireless/rt2x00/rt2x00debug.h @@ -30,9 +30,9 @@ struct rt2x00_dev; #define RT2X00DEBUGFS_REGISTER_ENTRY(__name, __type) \ struct reg##__name { \ - void (*read)(const struct rt2x00_dev *rt2x00dev, \ + void (*read)(struct rt2x00_dev *rt2x00dev, \ const unsigned int word, __type *data); \ - void (*write)(const struct rt2x00_dev *rt2x00dev, \ + void (*write)(struct rt2x00_dev *rt2x00dev, \ const unsigned int word, __type data); \ \ unsigned int word_size; \ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index ff399f8..a771a09 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -23,16 +23,12 @@ Abstract: rt2x00 generic device routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include #include "rt2x00.h" #include "rt2x00lib.h" +#include "rt2x00dump.h" /* * Ring handler. @@ -67,7 +63,21 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring); */ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) { - rt2x00_clear_link(&rt2x00dev->link); + rt2x00dev->link.count = 0; + rt2x00dev->link.vgc_level = 0; + + memset(&rt2x00dev->link.qual, 0, sizeof(rt2x00dev->link.qual)); + + /* + * The RX and TX percentage should start at 50% + * this will assure we will get at least get some + * decent value when the link tuner starts. + * The value will be dropped and overwritten with + * the correct (measured )value anyway during the + * first run of the link tuner. + */ + rt2x00dev->link.qual.rx_percentage = 50; + rt2x00dev->link.qual.tx_percentage = 50; /* * Reset the link tuner. @@ -179,26 +189,153 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state) rt2x00lib_start_link_tuner(rt2x00dev); } -static void rt2x00lib_precalculate_link_signal(struct link *link) +static void rt2x00lib_evaluate_antenna_sample(struct rt2x00_dev *rt2x00dev) +{ + enum antenna rx = rt2x00dev->link.ant.active.rx; + enum antenna tx = rt2x00dev->link.ant.active.tx; + int sample_a = + rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_A); + int sample_b = + rt2x00_get_link_ant_rssi_history(&rt2x00dev->link, ANTENNA_B); + + /* + * We are done sampling. Now we should evaluate the results. + */ + rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE; + + /* + * During the last period we have sampled the RSSI + * from both antenna's. It now is time to determine + * which antenna demonstrated the best performance. + * When we are already on the antenna with the best + * performance, then there really is nothing for us + * left to do. + */ + if (sample_a == sample_b) + return; + + if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) { + if (sample_a > sample_b && rx == ANTENNA_B) + rx = ANTENNA_A; + else if (rx == ANTENNA_A) + rx = ANTENNA_B; + } + + if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) { + if (sample_a > sample_b && tx == ANTENNA_B) + tx = ANTENNA_A; + else if (tx == ANTENNA_A) + tx = ANTENNA_B; + } + + rt2x00lib_config_antenna(rt2x00dev, rx, tx); +} + +static void rt2x00lib_evaluate_antenna_eval(struct rt2x00_dev *rt2x00dev) +{ + enum antenna rx = rt2x00dev->link.ant.active.rx; + enum antenna tx = rt2x00dev->link.ant.active.tx; + int rssi_curr = rt2x00_get_link_ant_rssi(&rt2x00dev->link); + int rssi_old = rt2x00_update_ant_rssi(&rt2x00dev->link, rssi_curr); + + /* + * Legacy driver indicates that we should swap antenna's + * when the difference in RSSI is greater that 5. This + * also should be done when the RSSI was actually better + * then the previous sample. + * When the difference exceeds the threshold we should + * sample the rssi from the other antenna to make a valid + * comparison between the 2 antennas. + */ + if ((rssi_curr - rssi_old) > -5 || (rssi_curr - rssi_old) < 5) + return; + + rt2x00dev->link.ant.flags |= ANTENNA_MODE_SAMPLE; + + if (rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) + rx = (rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; + + if (rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY) + tx = (tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; + + rt2x00lib_config_antenna(rt2x00dev, rx, tx); +} + +static void rt2x00lib_evaluate_antenna(struct rt2x00_dev *rt2x00dev) { - if (link->rx_failed || link->rx_success) - link->rx_percentage = - (link->rx_success * 100) / - (link->rx_failed + link->rx_success); + /* + * Determine if software diversity is enabled for + * either the TX or RX antenna (or both). + * Always perform this check since within the link + * tuner interval the configuration might have changed. + */ + rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY; + rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY; + + if (rt2x00dev->hw->conf.antenna_sel_rx == 0 && + rt2x00dev->default_ant.rx != ANTENNA_SW_DIVERSITY) + rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY; + if (rt2x00dev->hw->conf.antenna_sel_tx == 0 && + rt2x00dev->default_ant.tx != ANTENNA_SW_DIVERSITY) + rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY; + + if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) && + !(rt2x00dev->link.ant.flags & ANTENNA_TX_DIVERSITY)) { + rt2x00dev->link.ant.flags &= ~ANTENNA_MODE_SAMPLE; + return; + } + + /* + * If we have only sampled the data over the last period + * we should now harvest the data. Otherwise just evaluate + * the data. The latter should only be performed once + * every 2 seconds. + */ + if (rt2x00dev->link.ant.flags & ANTENNA_MODE_SAMPLE) + rt2x00lib_evaluate_antenna_sample(rt2x00dev); + else if (rt2x00dev->link.count & 1) + rt2x00lib_evaluate_antenna_eval(rt2x00dev); +} + +static void rt2x00lib_update_link_stats(struct link *link, int rssi) +{ + int avg_rssi = rssi; + + /* + * Update global RSSI + */ + if (link->qual.avg_rssi) + avg_rssi = MOVING_AVERAGE(link->qual.avg_rssi, rssi, 8); + link->qual.avg_rssi = avg_rssi; + + /* + * Update antenna RSSI + */ + if (link->ant.rssi_ant) + rssi = MOVING_AVERAGE(link->ant.rssi_ant, rssi, 8); + link->ant.rssi_ant = rssi; +} + +static void rt2x00lib_precalculate_link_signal(struct link_qual *qual) +{ + if (qual->rx_failed || qual->rx_success) + qual->rx_percentage = + (qual->rx_success * 100) / + (qual->rx_failed + qual->rx_success); else - link->rx_percentage = 50; + qual->rx_percentage = 50; - if (link->tx_failed || link->tx_success) - link->tx_percentage = - (link->tx_success * 100) / - (link->tx_failed + link->tx_success); + if (qual->tx_failed || qual->tx_success) + qual->tx_percentage = + (qual->tx_success * 100) / + (qual->tx_failed + qual->tx_success); else - link->tx_percentage = 50; + qual->tx_percentage = 50; - link->rx_success = 0; - link->rx_failed = 0; - link->tx_success = 0; - link->tx_failed = 0; + qual->rx_success = 0; + qual->rx_failed = 0; + qual->tx_success = 0; + qual->tx_failed = 0; } static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev, @@ -225,8 +362,8 @@ static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev, * defines to calculate the current link signal. */ signal = ((WEIGHT_RSSI * rssi_percentage) + - (WEIGHT_TX * rt2x00dev->link.tx_percentage) + - (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100; + (WEIGHT_TX * rt2x00dev->link.qual.tx_percentage) + + (WEIGHT_RX * rt2x00dev->link.qual.rx_percentage)) / 100; return (signal > 100) ? 100 : signal; } @@ -246,10 +383,9 @@ static void rt2x00lib_link_tuner(struct work_struct *work) /* * Update statistics. */ - rt2x00dev->ops->lib->link_stats(rt2x00dev); - + rt2x00dev->ops->lib->link_stats(rt2x00dev, &rt2x00dev->link.qual); rt2x00dev->low_level_stats.dot11FCSErrorCount += - rt2x00dev->link.rx_failed; + rt2x00dev->link.qual.rx_failed; /* * Only perform the link tuning when Link tuning @@ -259,10 +395,15 @@ static void rt2x00lib_link_tuner(struct work_struct *work) rt2x00dev->ops->lib->link_tuner(rt2x00dev); /* + * Evaluate antenna setup. + */ + rt2x00lib_evaluate_antenna(rt2x00dev); + + /* * Precalculate a portion of the link signal which is * in based on the tx/rx success/failure counters. */ - rt2x00lib_precalculate_link_signal(&rt2x00dev->link); + rt2x00lib_precalculate_link_signal(&rt2x00dev->link.qual); /* * Increase tuner counter, and reschedule the next link tuner run. @@ -350,8 +491,8 @@ void rt2x00lib_txdone(struct data_entry *entry, tx_status->ack_signal = 0; tx_status->excessive_retries = (status == TX_FAIL_RETRY); tx_status->retry_count = retry; - rt2x00dev->link.tx_success += success; - rt2x00dev->link.tx_failed += retry + fail; + rt2x00dev->link.qual.tx_success += success; + rt2x00dev->link.qual.tx_failed += retry + fail; if (!(tx_status->control.flags & IEEE80211_TXCTL_NO_ACK)) { if (success) @@ -371,9 +512,11 @@ void rt2x00lib_txdone(struct data_entry *entry, } /* - * Send the tx_status to mac80211, - * that method also cleans up the skb structure. + * Send the tx_status to mac80211 & debugfs. + * mac80211 will clean up the skb structure. */ + get_skb_desc(entry->skb)->frame_type = DUMP_FRAME_TXDONE; + rt2x00debug_dump_frame(rt2x00dev, entry->skb); ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status); entry->skb = NULL; } @@ -383,11 +526,14 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, struct rxdata_entry_desc *desc) { struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev; + struct interface *intf = &rt2x00dev->interface; struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; struct ieee80211_hw_mode *mode; struct ieee80211_rate *rate; + struct ieee80211_hdr *hdr; unsigned int i; int val = 0; + u16 fc; /* * Update RX statistics. @@ -412,17 +558,35 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb, } } - rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi); - rt2x00dev->link.rx_success++; + /* + * Only update link status if this is a beacon frame carrying our + * bssid. + */ + hdr = (struct ieee80211_hdr *) skb->data; + if (skb->len >= sizeof(struct ieee80211_hdr *)) { + fc = le16_to_cpu(hdr->frame_control); + if ((intf->type == IEEE80211_IF_TYPE_STA + || intf->type == IEEE80211_IF_TYPE_IBSS) + && is_beacon(fc) + && compare_ether_addr(hdr->addr3, intf->bssid) == 0) + rt2x00lib_update_link_stats(&rt2x00dev->link, + desc->rssi); + } + + rt2x00dev->link.qual.rx_success++; + rx_status->rate = val; rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi); rx_status->ssi = desc->rssi; rx_status->flag = desc->flags; + rx_status->antenna = rt2x00dev->link.ant.active.rx; /* - * Send frame to mac80211 + * Send frame to mac80211 & debugfs */ + get_skb_desc(skb)->frame_type = DUMP_FRAME_RXDONE; + rt2x00debug_dump_frame(rt2x00dev, skb); ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status); } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -431,36 +595,26 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); * TX descriptor initializer */ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, - struct ieee80211_hdr *ieee80211hdr, - unsigned int length, + struct sk_buff *skb, struct ieee80211_tx_control *control) { struct txdata_entry_desc desc; - struct data_ring *ring; + struct skb_desc *skbdesc = get_skb_desc(skb); + struct ieee80211_hdr *ieee80211hdr = skbdesc->data; + __le32 *txd = skbdesc->desc; int tx_rate; int bitrate; + int length; int duration; int residual; u16 frame_control; u16 seq_ctrl; - /* - * Make sure the descriptor is properly cleared. - */ - memset(&desc, 0x00, sizeof(desc)); - - /* - * Get ring pointer, if we fail to obtain the - * correct ring, then use the first TX ring. - */ - ring = rt2x00lib_get_ring(rt2x00dev, control->queue); - if (!ring) - ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0); + memset(&desc, 0, sizeof(desc)); - desc.cw_min = ring->tx_params.cw_min; - desc.cw_max = ring->tx_params.cw_max; - desc.aifs = ring->tx_params.aifs; + desc.cw_min = skbdesc->ring->tx_params.cw_min; + desc.cw_max = skbdesc->ring->tx_params.cw_max; + desc.aifs = skbdesc->ring->tx_params.aifs; /* * Identify queue @@ -482,12 +636,21 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, tx_rate = control->tx_rate; /* + * Check whether this frame is to be acked + */ + if (!(control->flags & IEEE80211_TXCTL_NO_ACK)) + __set_bit(ENTRY_TXD_ACK, &desc.flags); + + /* * Check if this is a RTS/CTS frame */ if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { __set_bit(ENTRY_TXD_BURST, &desc.flags); - if (is_rts_frame(frame_control)) + if (is_rts_frame(frame_control)) { __set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags); + __set_bit(ENTRY_TXD_ACK, &desc.flags); + } else + __clear_bit(ENTRY_TXD_ACK, &desc.flags); if (control->rts_cts_rate) tx_rate = control->rts_cts_rate; } @@ -532,17 +695,18 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP); desc.service = 0x04; + length = skbdesc->data_len + FCS_LEN; if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) { - desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f; - desc.length_low = ((length + FCS_LEN) & 0x3f); + desc.length_high = (length >> 6) & 0x3f; + desc.length_low = length & 0x3f; } else { bitrate = DEVICE_GET_RATE_FIELD(tx_rate, RATE); /* * Convert length to microseconds. */ - residual = get_duration_res(length + FCS_LEN, bitrate); - duration = get_duration(length + FCS_LEN, bitrate); + residual = get_duration_res(length, bitrate); + duration = get_duration(length, bitrate); if (residual != 0) { duration++; @@ -565,8 +729,23 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev, desc.signal |= 0x08; } - rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, - ieee80211hdr, length, control); + rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc, ieee80211hdr, + skbdesc->data_len, control); + + /* + * Update ring entry. + */ + skbdesc->entry->skb = skb; + memcpy(&skbdesc->entry->tx_status.control, control, sizeof(*control)); + + /* + * The frame has been completely initialized and ready + * for sending to the device. The caller will push the + * frame to the device, but we are going to push the + * frame to debugfs here. + */ + skbdesc->frame_type = DUMP_FRAME_TX; + rt2x00debug_dump_frame(rt2x00dev, skb); } EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc); @@ -1008,7 +1187,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) /* * Reset current working type. */ - rt2x00dev->interface.type = INVALID_INTERFACE; + rt2x00dev->interface.type = IEEE80211_IF_TYPE_INVALID; /* * Allocate ring array. diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h new file mode 100644 index 0000000..99f3f36 --- /dev/null +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h @@ -0,0 +1,121 @@ +/* + Copyright (C) 2004 - 2007 rt2x00 SourceForge Project + + + 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. + */ + +/* + Module: rt2x00dump + Abstract: Data structures for the rt2x00debug & userspace. + */ + +#ifndef RT2X00DUMP_H +#define RT2X00DUMP_H + +/** + * DOC: Introduction + * + * This header is intended to be exported to userspace, + * to make the structures and enumerations available to userspace + * applications. This means that all data types should be exportable. + * + * When rt2x00 is compiled with debugfs support enabled, + * it is possible to capture all data coming in and out of the device + * by reading the frame dump file. This file can have only a single reader. + * The following frames will be reported: + * - All incoming frames (rx) + * - All outgoing frames (tx, including beacon and atim) + * - All completed frames (txdone including atim) + * + * The data is send to the file using the following format: + * + * [rt2x00dump header][hardware descriptor][ieee802.11 frame] + * + * rt2x00dump header: The description of the dumped frame, as well as + * additional information usefull for debugging. See &rt2x00dump_hdr. + * hardware descriptor: Descriptor that was used to receive or transmit + * the frame. + * ieee802.11 frame: The actual frame that was received or transmitted. + */ + +/** + * enum rt2x00_dump_type - Frame type + * + * These values are used for the @type member of &rt2x00dump_hdr. + * @DUMP_FRAME_RXDONE: This frame has been received by the hardware. + * @DUMP_FRAME_TX: This frame is queued for transmission to the hardware. + * @DUMP_FRAME_TXDONE: This frame indicates the device has handled + * the tx event which has either succeeded or failed. A frame + * with this type should also have been reported with as a + * %DUMP_FRAME_TX frame. + */ +enum rt2x00_dump_type { + DUMP_FRAME_RXDONE = 1, + DUMP_FRAME_TX = 2, + DUMP_FRAME_TXDONE = 3, +}; + +/** + * struct rt2x00dump_hdr - Dump frame header + * + * Each frame dumped to the debugfs file starts with this header + * attached. This header contains the description of the actual + * frame which was dumped. + * + * New fields inside the structure must be appended to the end of + * the structure. This way userspace tools compiled for earlier + * header versions can still correctly handle the frame dump + * (although they will not handle all data passed to them in the dump). + * + * @version: Header version should always be set to %DUMP_HEADER_VERSION. + * This field must be checked by userspace to determine if it can + * handle this frame. + * @header_length: The length of the &rt2x00dump_hdr structure. This is + * used for compatibility reasons so userspace can easily determine + * the location of the next field in the dump. + * @desc_length: The length of the device descriptor. + * @data_length: The length of the frame data (including the ieee802.11 header. + * @chip_rt: RT chipset + * @chip_rf: RF chipset + * @chip_rev: Chipset revision + * @type: The frame type (&rt2x00_dump_type) + * @ring_index: The index number of the data ring. + * @entry_index: The index number of the entry inside the data ring. + * @timestamp_sec: Timestamp - seconds + * @timestamp_usec: Timestamp - microseconds + */ +struct rt2x00dump_hdr { + __le32 version; +#define DUMP_HEADER_VERSION 2 + + __le32 header_length; + __le32 desc_length; + __le32 data_length; + + __le16 chip_rt; + __le16 chip_rf; + __le32 chip_rev; + + __le16 type; + __u8 ring_index; + __u8 entry_index; + + __le32 timestamp_sec; + __le32 timestamp_usec; +}; + +#endif /* RT2X00DUMP_H */ diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index 236025f..0a475e4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -23,11 +23,6 @@ Abstract: rt2x00 firmware loading routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include #include diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 06d9bc0..108488d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -53,6 +53,8 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev); void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac); void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid); void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, const int type); +void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, + enum antenna rx, enum antenna tx); void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, const int force_config); @@ -78,6 +80,7 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2X00_LIB_DEBUGFS void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); +void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); #else static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) { @@ -86,6 +89,11 @@ static inline void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) { } + +static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, + struct sk_buff *skb) +{ +} #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ /* diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 85ea8a8..bae4442 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -23,11 +23,6 @@ Abstract: rt2x00 generic mac80211 routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include @@ -247,7 +242,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw, return; intf->id = 0; - intf->type = INVALID_INTERFACE; + intf->type = IEEE80211_IF_TYPE_INVALID; memset(&intf->bssid, 0x00, ETH_ALEN); memset(&intf->mac, 0x00, ETH_ALEN); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2780df0..abeffdb 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -23,11 +23,6 @@ Abstract: rt2x00 generic pci device routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00pci" - #include #include #include @@ -43,9 +38,9 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; - struct data_ring *ring = - rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON); - struct data_entry *entry = rt2x00_get_data_entry(ring); + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; /* * Just in case mac80211 doesn't set this correctly, @@ -53,14 +48,22 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); /* - * Update the beacon entry. + * Fill in skb descriptor */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len; + desc->desc = entry->priv; + desc->data = skb->data; + desc->ring = ring; + desc->entry = entry; + memcpy(entry->data_addr, skb->data, skb->len); - rt2x00lib_write_tx_desc(rt2x00dev, entry->priv, - (struct ieee80211_hdr *)skb->data, - skb->len, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Enable beacon generation. @@ -78,9 +81,9 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, struct data_ring *ring, struct sk_buff *skb, struct ieee80211_tx_control *control) { - struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data; struct data_entry *entry = rt2x00_get_data_entry(ring); - struct data_desc *txd = entry->priv; + __le32 *txd = entry->priv; + struct skb_desc *desc; u32 word; if (rt2x00_ring_full(ring)) { @@ -100,11 +103,19 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, return -EINVAL; } - entry->skb = skb; - memcpy(&entry->tx_status.control, control, sizeof(*control)); + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len; + desc->desc = entry->priv; + desc->data = skb->data; + desc->ring = ring; + desc->entry = entry; + memcpy(entry->data_addr, skb->data, skb->len); - rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr, - skb->len, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); rt2x00_ring_index_inc(ring); @@ -116,15 +127,16 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); /* - * RX data handlers. + * TX/RX data handlers. */ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring = rt2x00dev->rx; struct data_entry *entry; - struct data_desc *rxd; struct sk_buff *skb; + struct skb_desc *skbdesc; struct rxdata_entry_desc desc; + __le32 *rxd; u32 word; while (1) { @@ -135,7 +147,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) break; - memset(&desc, 0x00, sizeof(desc)); + memset(&desc, 0, sizeof(desc)); rt2x00dev->ops->lib->fill_rxdone(entry, &desc); /* @@ -151,6 +163,17 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) memcpy(skb->data, entry->data_addr, desc.size); /* + * Fill in skb descriptor + */ + skbdesc = get_skb_desc(skb); + skbdesc->desc_len = entry->ring->desc_size; + skbdesc->data_len = skb->len; + skbdesc->desc = entry->priv; + skbdesc->data = skb->data; + skbdesc->ring = ring; + skbdesc->entry = entry; + + /* * Send the frame to rt2x00lib for further processing. */ rt2x00lib_rxdone(entry, skb, &desc); @@ -165,6 +188,37 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); +void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, + const int tx_status, const int retry) +{ + u32 word; + + rt2x00lib_txdone(entry, tx_status, retry); + + /* + * Make this entry available for reuse. + */ + entry->flags = 0; + + rt2x00_desc_read(entry->priv, 0, &word); + rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); + rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); + rt2x00_desc_write(entry->priv, 0, word); + + rt2x00_ring_index_done_inc(entry->ring); + + /* + * If the data ring was full before the txdone handler + * we must make sure the packet queue in the mac80211 stack + * is reenabled when the txdone handler has finished. + */ + if (!rt2x00_ring_full(entry->ring)) + ieee80211_wake_queue(rt2x00dev->hw, + entry->tx_status.control.queue); + +} +EXPORT_SYMBOL_GPL(rt2x00pci_txdone); + /* * Device initialization handlers. */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 82adeac..2d1eb81 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -57,7 +57,7 @@ /* * Register access. */ -static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, const unsigned long offset, u32 *value) { @@ -65,14 +65,14 @@ static inline void rt2x00pci_register_read(const struct rt2x00_dev *rt2x00dev, } static inline void -rt2x00pci_register_multiread(const struct rt2x00_dev *rt2x00dev, +rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev, const unsigned long offset, void *value, const u16 length) { memcpy_fromio(value, rt2x00dev->csr_addr + offset, length); } -static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev, const unsigned long offset, u32 value) { @@ -80,7 +80,7 @@ static inline void rt2x00pci_register_write(const struct rt2x00_dev *rt2x00dev, } static inline void -rt2x00pci_register_multiwrite(const struct rt2x00_dev *rt2x00dev, +rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, const unsigned long offset, void *value, const u16 length) { @@ -101,9 +101,11 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, struct ieee80211_tx_control *control); /* - * RX data handlers. + * RX/TX data handlers. */ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); +void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry, + const int tx_status, const int retry); /* * Device initialization handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index a0f8b8e..34a96d4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c @@ -23,11 +23,6 @@ Abstract: rt2x00 rfkill routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00lib" - #include #include #include @@ -68,8 +63,10 @@ static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev) struct rt2x00_dev *rt2x00dev = poll_dev->private; int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); - if (rt2x00dev->rfkill->state != state) + if (rt2x00dev->rfkill->state != state) { input_report_key(poll_dev->input, KEY_WLAN, 1); + input_report_key(poll_dev->input, KEY_WLAN, 0); + } } int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) @@ -92,6 +89,13 @@ int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev) return retval; } + /* + * Force initial poll which will detect the initial device state, + * and correctly sends the signal to the rfkill layer about this + * state. + */ + rt2x00rfkill_poll(rt2x00dev->poll_dev); + return 0; } @@ -114,26 +118,41 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev) rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); if (!rt2x00dev->rfkill) { ERROR(rt2x00dev, "Failed to allocate rfkill handler.\n"); - return -ENOMEM; + goto exit; } rt2x00dev->rfkill->name = rt2x00dev->ops->name; rt2x00dev->rfkill->data = rt2x00dev; - rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); + rt2x00dev->rfkill->state = -1; rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; rt2x00dev->poll_dev = input_allocate_polled_device(); if (!rt2x00dev->poll_dev) { ERROR(rt2x00dev, "Failed to allocate polled device.\n"); - rfkill_free(rt2x00dev->rfkill); - return -ENOMEM; + goto exit_free_rfkill; } rt2x00dev->poll_dev->private = rt2x00dev; rt2x00dev->poll_dev->poll = rt2x00rfkill_poll; rt2x00dev->poll_dev->poll_interval = RFKILL_POLL_INTERVAL; + rt2x00dev->poll_dev->input->name = rt2x00dev->ops->name; + rt2x00dev->poll_dev->input->phys = wiphy_name(rt2x00dev->hw->wiphy); + rt2x00dev->poll_dev->input->id.bustype = BUS_HOST; + rt2x00dev->poll_dev->input->id.vendor = 0x1814; + rt2x00dev->poll_dev->input->id.product = rt2x00dev->chip.rt; + rt2x00dev->poll_dev->input->id.version = rt2x00dev->chip.rev; + rt2x00dev->poll_dev->input->dev.parent = device; + rt2x00dev->poll_dev->input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_WLAN, rt2x00dev->poll_dev->input->keybit); + return 0; + +exit_free_rfkill: + rfkill_free(rt2x00dev->rfkill); + +exit: + return -ENOMEM; } void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h index 1a864d3..5b32f3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ring.h +++ b/drivers/net/wireless/rt2x00/rt2x00ring.h @@ -27,19 +27,27 @@ #define RT2X00RING_H /* - * data_desc - * Each data entry also contains a descriptor which is used by the - * device to determine what should be done with the packet and - * what the current status is. - * This structure is greatly simplified, but the descriptors - * are basically a list of little endian 32 bit values. - * Make the array by default 1 word big, this will allow us - * to use sizeof() correctly. + * skb_desc + * Descriptor information for the skb buffer */ -struct data_desc { - __le32 word[1]; +struct skb_desc { + unsigned int frame_type; + + unsigned int desc_len; + unsigned int data_len; + + void *desc; + void *data; + + struct data_ring *ring; + struct data_entry *entry; }; +static inline struct skb_desc* get_skb_desc(struct sk_buff *skb) +{ + return (struct skb_desc*)&skb->cb[0]; +} + /* * rxdata_entry_desc * Summary of information that has been read from the @@ -66,6 +74,7 @@ struct txdata_entry_desc { #define ENTRY_TXD_MORE_FRAG 4 #define ENTRY_TXD_REQ_TIMESTAMP 5 #define ENTRY_TXD_BURST 6 +#define ENTRY_TXD_ACK 7 /* * Queue ID. ID's 0-4 are data TX rings @@ -253,16 +262,16 @@ static inline int rt2x00_ring_free(struct data_ring *ring) /* * TX/RX Descriptor access functions. */ -static inline void rt2x00_desc_read(struct data_desc *desc, +static inline void rt2x00_desc_read(__le32 *desc, const u8 word, u32 *value) { - *value = le32_to_cpu(desc->word[word]); + *value = le32_to_cpu(desc[word]); } -static inline void rt2x00_desc_write(struct data_desc *desc, +static inline void rt2x00_desc_write(__le32 *desc, const u8 word, const u32 value) { - desc->word[word] = cpu_to_le32(value); + desc[word] = cpu_to_le32(value); } #endif /* RT2X00RING_H */ diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 1f5675d..82e95b9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -23,14 +23,10 @@ Abstract: rt2x00 generic usb device routines. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt2x00usb" - #include #include #include +#include #include "rt2x00.h" #include "rt2x00usb.h" @@ -38,7 +34,7 @@ /* * Interfacing with the HW. */ -int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, +int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, const u8 request, const u8 requesttype, const u16 offset, const u16 value, void *buffer, const u16 buffer_length, @@ -52,6 +48,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, (requesttype == USB_VENDOR_REQUEST_IN) ? usb_rcvctrlpipe(usb_dev, 0) : usb_sndctrlpipe(usb_dev, 0); + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { status = usb_control_msg(usb_dev, pipe, request, requesttype, value, offset, buffer, buffer_length, @@ -76,13 +73,15 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request); -int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev, - const u8 request, const u8 requesttype, - const u16 offset, void *buffer, - const u16 buffer_length, const int timeout) +int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, + const u8 request, const u8 requesttype, + const u16 offset, void *buffer, + const u16 buffer_length, const int timeout) { int status; + BUG_ON(!mutex_is_locked(&rt2x00dev->usb_cache_mutex)); + /* * Check for Cache availability. */ @@ -103,6 +102,25 @@ int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev, return status; } +EXPORT_SYMBOL_GPL(rt2x00usb_vendor_req_buff_lock); + +int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, + const u8 request, const u8 requesttype, + const u16 offset, void *buffer, + const u16 buffer_length, const int timeout) +{ + int status; + + mutex_lock(&rt2x00dev->usb_cache_mutex); + + status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, + requesttype, offset, buffer, + buffer_length, timeout); + + mutex_unlock(&rt2x00dev->usb_cache_mutex); + + return status; +} EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); /* @@ -113,7 +131,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct data_entry *entry = (struct data_entry *)urb->context; struct data_ring *ring = entry->ring; struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; - struct data_desc *txd = (struct data_desc *)entry->skb->data; + __le32 *txd = (__le32 *)entry->skb->data; u32 word; int tx_status; @@ -158,7 +176,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, struct usb_device *usb_dev = interface_to_usbdev(rt2x00dev_usb(rt2x00dev)); struct data_entry *entry = rt2x00_get_data_entry(ring); - int pipe = usb_sndbulkpipe(usb_dev, 1); + struct skb_desc *desc; u32 length; if (rt2x00_ring_full(ring)) { @@ -181,12 +199,18 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, skb_push(skb, ring->desc_size); memset(skb->data, 0, ring->desc_size); - rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, - (struct ieee80211_hdr *)(skb->data + - ring->desc_size), - skb->len - ring->desc_size, control); - memcpy(&entry->tx_status.control, control, sizeof(*control)); - entry->skb = skb; + /* + * Fill in skb descriptor + */ + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; + + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * USB devices cannot blindly pass the skb->len as the @@ -199,7 +223,7 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, * Initialize URB and send the frame to the device. */ __set_bit(ENTRY_OWNER_NIC, &entry->flags); - usb_fill_bulk_urb(entry->priv, usb_dev, pipe, + usb_fill_bulk_urb(entry->priv, usb_dev, usb_sndbulkpipe(usb_dev, 1), skb->data, length, rt2x00usb_interrupt_txdone, entry); usb_submit_urb(entry->priv, GFP_ATOMIC); @@ -221,6 +245,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct data_ring *ring = entry->ring; struct rt2x00_dev *rt2x00dev = ring->rt2x00dev; struct sk_buff *skb; + struct skb_desc *skbdesc; struct rxdata_entry_desc desc; int frame_size; @@ -236,7 +261,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) if (urb->actual_length < entry->ring->desc_size || urb->status) goto skip_entry; - memset(&desc, 0x00, sizeof(desc)); + memset(&desc, 0, sizeof(desc)); rt2x00dev->ops->lib->fill_rxdone(entry, &desc); /* @@ -259,6 +284,17 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) skb_trim(entry->skb, desc.size); /* + * Fill in skb descriptor + */ + skbdesc = get_skb_desc(entry->skb); + skbdesc->desc_len = entry->ring->desc_size; + skbdesc->data_len = entry->skb->len; + skbdesc->desc = entry->skb->data - skbdesc->desc_len; + skbdesc->data = entry->skb->data; + skbdesc->ring = ring; + skbdesc->entry = entry; + + /* * Send the frame to rt2x00lib for further processing. */ rt2x00lib_rxdone(entry, entry->skb, &desc); @@ -487,6 +523,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, rt2x00dev->dev = usb_intf; rt2x00dev->ops = ops; rt2x00dev->hw = hw; + mutex_init(&rt2x00dev->usb_cache_mutex); rt2x00dev->usb_maxpacket = usb_maxpacket(usb_dev, usb_sndbulkpipe(usb_dev, 1), 1); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 2681abe..2fa45c5 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -91,7 +91,7 @@ * a buffer allocated by kmalloc. Failure to do so can lead * to unexpected behavior depending on the architecture. */ -int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, +int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, const u8 request, const u8 requesttype, const u16 offset, const u16 value, void *buffer, const u16 buffer_length, @@ -107,18 +107,25 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev, * kmalloc. Hence the reason for using a previously allocated cache * which has been allocated properly. */ -int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev, +int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, const u8 request, const u8 requesttype, const u16 offset, void *buffer, const u16 buffer_length, const int timeout); /* + * A version of rt2x00usb_vendor_request_buff which must be called + * if the usb_cache_mutex is already held. */ +int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, + const u8 request, const u8 requesttype, + const u16 offset, void *buffer, + const u16 buffer_length, const int timeout); + +/* * Simple wrapper around rt2x00usb_vendor_request to write a single * command to the device. Since we don't use the buffer argument we * don't have to worry about kmalloc here. */ -static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev - *rt2x00dev, +static inline int rt2x00usb_vendor_request_sw(struct rt2x00_dev *rt2x00dev, const u8 request, const u16 offset, const u16 value, @@ -134,8 +141,8 @@ static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev * from the device. Note that the eeprom argument _must_ be allocated using * kmalloc for correct handling inside the kernel USB layer. */ -static inline int rt2x00usb_eeprom_read(const struct rt2x00_dev *rt2x00dev, - __le16 *eeprom, const u16 lenght) +static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, + __le16 *eeprom, const u16 lenght) { int timeout = REGISTER_TIMEOUT * (lenght / sizeof(u16)); diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 01dbef1..13c8086 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -24,11 +24,6 @@ Supported chipsets: RT2561, RT2561s, RT2661. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt61pci" - #include #include #include @@ -52,7 +47,7 @@ * the access attempt is considered to have failed, * and we will print an error. */ -static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev) +static u32 rt61pci_bbp_check(struct rt2x00_dev *rt2x00dev) { u32 reg; unsigned int i; @@ -67,7 +62,7 @@ static u32 rt61pci_bbp_check(const struct rt2x00_dev *rt2x00dev) return reg; } -static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { u32 reg; @@ -93,7 +88,7 @@ static void rt61pci_bbp_write(const struct rt2x00_dev *rt2x00dev, rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); } -static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { u32 reg; @@ -130,7 +125,7 @@ static void rt61pci_bbp_read(const struct rt2x00_dev *rt2x00dev, *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); } -static void rt61pci_rf_write(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u32 value) { u32 reg; @@ -160,7 +155,7 @@ rf_write: rt2x00_rf_write(rt2x00dev, word, value); } -static void rt61pci_mcu_request(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1) { @@ -220,13 +215,13 @@ static void rt61pci_eepromregister_write(struct eeprom_93cx6 *eeprom) #ifdef CONFIG_RT2X00_LIB_DEBUGFS #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) -static void rt61pci_read_csr(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_read_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { rt2x00pci_register_read(rt2x00dev, CSR_OFFSET(word), data); } -static void rt61pci_write_csr(const struct rt2x00_dev *rt2x00dev, +static void rt61pci_write_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt2x00pci_register_write(rt2x00dev, CSR_OFFSET(word), data); @@ -411,8 +406,7 @@ static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev, } static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, - const int antenna_rx) + struct antenna_setup *ant) { u8 r3; u8 r4; @@ -423,32 +417,39 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, rt61pci_bbp_read(rt2x00dev, 77, &r77); rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, - !rt2x00_rf(&rt2x00dev->chip, RF5225)); + rt2x00_rf(&rt2x00dev->chip, RF5325)); - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + /* + * Configure the RX antenna. + */ + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !!(rt2x00dev->curr_hwmode != HWMODE_A)); + (rt2x00dev->curr_hwmode != HWMODE_A)); break; case ANTENNA_A: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); - if (rt2x00dev->curr_hwmode == HWMODE_A) - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); else - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); - if (rt2x00dev->curr_hwmode == HWMODE_A) - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); else - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); break; } @@ -458,8 +459,7 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, } static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, - const int antenna_rx) + struct antenna_setup *ant) { u8 r3; u8 r4; @@ -470,22 +470,31 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt61pci_bbp_read(rt2x00dev, 77, &r77); rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, - !rt2x00_rf(&rt2x00dev->chip, RF2527)); + rt2x00_rf(&rt2x00dev->chip, RF2529)); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + /* + * Configure the RX antenna. + */ + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); break; case ANTENNA_A: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); break; } @@ -501,23 +510,18 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); - if (p1 != 0xff) { - rt2x00_set_field32(®, MAC_CSR13_BIT4, !!p1); - rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); - } - if (p2 != 0xff) { - rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); - rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); - rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); - } + rt2x00_set_field32(®, MAC_CSR13_BIT4, p1); + rt2x00_set_field32(®, MAC_CSR13_BIT12, 0); + + rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2); + rt2x00_set_field32(®, MAC_CSR13_BIT11, 0); + + rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); } static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, - const int antenna_rx) + struct antenna_setup *ant) { - u16 eeprom; u8 r3; u8 r4; u8 r77; @@ -525,70 +529,36 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev, rt61pci_bbp_read(rt2x00dev, 3, &r3); rt61pci_bbp_read(rt2x00dev, 4, &r4); rt61pci_bbp_read(rt2x00dev, 77, &r77); - rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); - rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); - - if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); - rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1); - rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); - } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) { - if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) { - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); - rt61pci_bbp_write(rt2x00dev, 77, r77); - } - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); - } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && - rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); - rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); - - switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { - case 0: - rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); - break; - case 1: - rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); - break; - case 2: - rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); - break; - case 3: - rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); - break; - } - } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) && - !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) { - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); + /* FIXME: Antenna selection for the rf 2529 is very confusing in the + * legacy driver. The code below should be ok for non-diversity setups. + */ - switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { - case 0: - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); - rt61pci_bbp_write(rt2x00dev, 77, r77); - rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1); - break; - case 1: - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); - rt61pci_bbp_write(rt2x00dev, 77, r77); - rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0); - break; - case 2: - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); - rt61pci_bbp_write(rt2x00dev, 77, r77); - rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); - break; - case 3: - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); - rt61pci_bbp_write(rt2x00dev, 77, r77); - rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); - break; - } + /* + * Configure the RX antenna. + */ + switch (ant->rx) { + case ANTENNA_A: + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); + rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0); + break; + case ANTENNA_SW_DIVERSITY: + case ANTENNA_HW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ + case ANTENNA_B: + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); + rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1); + break; } + rt61pci_bbp_write(rt2x00dev, 77, r77); rt61pci_bbp_write(rt2x00dev, 3, r3); rt61pci_bbp_write(rt2x00dev, 4, r4); } @@ -625,46 +595,44 @@ static const struct antenna_sel antenna_sel_bg[] = { }; static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, const int antenna_rx) + struct antenna_setup *ant) { const struct antenna_sel *sel; unsigned int lna; unsigned int i; u32 reg; - rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); - if (rt2x00dev->curr_hwmode == HWMODE_A) { sel = antenna_sel_a; lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); - - rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); - rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); } else { sel = antenna_sel_bg; lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); - - rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); - rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); + rt2x00pci_register_read(rt2x00dev, PHY_CSR0, ®); + + rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, + (rt2x00dev->curr_hwmode == HWMODE_B || + rt2x00dev->curr_hwmode == HWMODE_G)); + rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, + (rt2x00dev->curr_hwmode == HWMODE_A)); + rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg); if (rt2x00_rf(&rt2x00dev->chip, RF5225) || rt2x00_rf(&rt2x00dev->chip, RF5325)) - rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); + rt61pci_config_antenna_5x(rt2x00dev, ant); else if (rt2x00_rf(&rt2x00dev->chip, RF2527)) - rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); + rt61pci_config_antenna_2x(rt2x00dev, ant); else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) { if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) - rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, - antenna_rx); + rt61pci_config_antenna_2x(rt2x00dev, ant); else - rt61pci_config_antenna_2529(rt2x00dev, antenna_tx, - antenna_rx); + rt61pci_config_antenna_2529(rt2x00dev, ant); } } @@ -709,8 +677,7 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) - rt61pci_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx, - libconf->conf->antenna_sel_rx); + rt61pci_config_antenna(rt2x00dev, &libconf->ant); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt61pci_config_duration(rt2x00dev, libconf); } @@ -721,7 +688,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev, static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) { u32 reg; - u16 led_reg; u8 arg0; u8 arg1; @@ -730,15 +696,14 @@ static void rt61pci_enable_led(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, MAC_CSR14_OFF_PERIOD, 30); rt2x00pci_register_write(rt2x00dev, MAC_CSR14, reg); - led_reg = rt2x00dev->led_reg; - rt2x00_set_field16(&led_reg, MCU_LEDCS_RADIO_STATUS, 1); - if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) - rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_A_STATUS, 1); - else - rt2x00_set_field16(&led_reg, MCU_LEDCS_LINK_BG_STATUS, 1); + rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); + rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, + (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); + rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, + (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); - arg0 = led_reg & 0xff; - arg1 = (led_reg >> 8) & 0xff; + arg0 = rt2x00dev->led_reg & 0xff; + arg1 = (rt2x00dev->led_reg >> 8) & 0xff; rt61pci_mcu_request(rt2x00dev, MCU_LED, 0xff, arg0, arg1); } @@ -792,7 +757,8 @@ static void rt61pci_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) /* * Link tuning */ -static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev) +static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, + struct link_qual *qual) { u32 reg; @@ -800,14 +766,13 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev) * Update FCS error count from register. */ rt2x00pci_register_read(rt2x00dev, STA_CSR0, ®); - rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); + qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); /* * Update False CCA count from register. */ rt2x00pci_register_read(rt2x00dev, STA_CSR1, ®); - rt2x00dev->link.false_cca = - rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); + qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); } static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) @@ -904,11 +869,11 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) * r17 does not yet exceed upper limit, continue and base * the r17 tuning on the false CCA count. */ - if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { + if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { if (++r17 > up_bound) r17 = up_bound; rt61pci_bbp_write(rt2x00dev, 17, r17); - } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { + } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { if (--r17 < low_bound) r17 = low_bound; rt61pci_bbp_write(rt2x00dev, 17, r17); @@ -1026,7 +991,7 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, void *data, static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring = rt2x00dev->rx; - struct data_desc *rxd; + __le32 *rxd; unsigned int i; u32 word; @@ -1051,7 +1016,7 @@ static void rt61pci_init_rxring(struct rt2x00_dev *rt2x00dev) static void rt61pci_init_txring(struct rt2x00_dev *rt2x00dev, const int queue) { struct data_ring *ring = rt2x00lib_get_ring(rt2x00dev, queue); - struct data_desc *txd; + __le32 *txd; unsigned int i; u32 word; @@ -1565,7 +1530,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, * TX descriptor initialization */ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, @@ -1608,7 +1573,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, - !(control->flags & IEEE80211_TXCTL_NO_ACK)); + test_bit(ENTRY_TXD_ACK, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, @@ -1649,16 +1614,16 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, } rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - if (queue == IEEE80211_TX_QUEUE_DATA0) - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA1) - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA2) - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA3) - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, 1); - else if (queue == IEEE80211_TX_QUEUE_DATA4) - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, 1); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, + (queue == IEEE80211_TX_QUEUE_DATA0)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, + (queue == IEEE80211_TX_QUEUE_DATA1)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, + (queue == IEEE80211_TX_QUEUE_DATA2)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, + (queue == IEEE80211_TX_QUEUE_DATA3)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_MGMT, + (queue == IEEE80211_TX_QUEUE_DATA4)); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); } @@ -1709,7 +1674,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) static void rt61pci_fill_rxdone(struct data_entry *entry, struct rxdata_entry_desc *desc) { - struct data_desc *rxd = entry->priv; + __le32 *rxd = entry->priv; u32 word0; u32 word1; @@ -1738,7 +1703,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_ring *ring; struct data_entry *entry; - struct data_desc *txd; + struct data_entry *entry_done; + __le32 *txd; u32 word; u32 reg; u32 old_reg; @@ -1791,30 +1757,25 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) !rt2x00_get_field32(word, TXD_W0_VALID)) return; + entry_done = rt2x00_get_data_entry_done(ring); + while (entry != entry_done) { + /* Catch up. Just report any entries we missed as + * failed. */ + WARNING(rt2x00dev, + "TX status report missed for entry %p\n", + entry_done); + rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER, + 0); + entry_done = rt2x00_get_data_entry_done(ring); + } + /* * Obtain the status about this packet. */ tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); - rt2x00lib_txdone(entry, tx_status, retry); - - /* - * Make this entry available for reuse. - */ - entry->flags = 0; - rt2x00_set_field32(&word, TXD_W0_VALID, 0); - rt2x00_desc_write(txd, 0, word); - rt2x00_ring_index_done_inc(entry->ring); - - /* - * If the data ring was full before the txdone handler - * we must make sure the packet queue in the mac80211 stack - * is reenabled when the txdone handler has finished. - */ - if (!rt2x00_ring_full(ring)) - ieee80211_wake_queue(rt2x00dev->hw, - entry->tx_status.control.queue); + rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry); } } @@ -1908,8 +1869,10 @@ static int rt61pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); + rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, + ANTENNA_B); + rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, + ANTENNA_B); rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); @@ -2013,11 +1976,17 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) } /* + * Determine number of antenna's. + */ + if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) + __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); + + /* * Identify default antenna configuration. */ - rt2x00dev->hw->conf.antenna_sel_tx = + rt2x00dev->default_ant.tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); - rt2x00dev->hw->conf.antenna_sel_rx = + rt2x00dev->default_ant.rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* @@ -2027,12 +1996,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags); /* - * Determine number of antenna's. - */ - if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) - __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); - - /* * Detect if this device has an hardware controlled radio. */ #ifdef CONFIG_RT61PCI_RFKILL @@ -2060,6 +2023,38 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); /* + * When working with a RF2529 chip without double antenna + * the antenna settings should be gathered from the NIC + * eeprom word. + */ + if (rt2x00_rf(&rt2x00dev->chip, RF2529) && + !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) { + switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) { + case 0: + rt2x00dev->default_ant.tx = ANTENNA_B; + rt2x00dev->default_ant.rx = ANTENNA_A; + break; + case 1: + rt2x00dev->default_ant.tx = ANTENNA_B; + rt2x00dev->default_ant.rx = ANTENNA_B; + break; + case 2: + rt2x00dev->default_ant.tx = ANTENNA_A; + rt2x00dev->default_ant.rx = ANTENNA_A; + break; + case 3: + rt2x00dev->default_ant.tx = ANTENNA_A; + rt2x00dev->default_ant.rx = ANTENNA_B; + break; + } + + if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) + rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY; + if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) + rt2x00dev->default_ant.rx = ANTENNA_SW_DIVERSITY; + } + + /* * Store led settings, for correct led behaviour. * If the eeprom value is invalid, * switch to default led mode. @@ -2414,6 +2409,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; /* * Just in case the ieee80211 doesn't set this, @@ -2421,6 +2419,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); /* * We need to append the descriptor in front of the @@ -2434,15 +2434,23 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, } /* - * First we create the beacon. + * Add the descriptor in front of the skb. + */ + skb_push(skb, ring->desc_size); + memset(skb->data, 0, ring->desc_size); + + /* + * Fill in skb descriptor */ - skb_push(skb, TXD_DESC_SIZE); - memset(skb->data, 0, TXD_DESC_SIZE); + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; - rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, - (struct ieee80211_hdr *)(skb->data + - TXD_DESC_SIZE), - skb->len - TXD_DESC_SIZE, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Write entire beacon with descriptor to register, @@ -2498,7 +2506,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { }; static const struct rt2x00_ops rt61pci_ops = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .rxd_size = RXD_DESC_SIZE, .txd_size = TXD_DESC_SIZE, .eeprom_size = EEPROM_SIZE, @@ -2535,7 +2543,7 @@ MODULE_FIRMWARE(FIRMWARE_RT2661); MODULE_LICENSE("GPL"); static struct pci_driver rt61pci_driver = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .id_table = rt61pci_device_table, .probe = rt2x00pci_probe, .remove = __devexit_p(rt2x00pci_remove), diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 6721d7d..4c6524e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -1077,13 +1077,19 @@ struct hw_pairwise_ta_entry { * R4: RX antenna control * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) */ -#define BBP_R4_RX_ANTENNA FIELD8(0x03) + +/* + * ANTENNA_CONTROL semantics (guessed): + * 0x1: Software controlled antenna switching (fixed or SW diversity) + * 0x2: Hardware diversity. + */ +#define BBP_R4_RX_ANTENNA_CONTROL FIELD8(0x03) #define BBP_R4_RX_FRAME_END FIELD8(0x20) /* * R77 */ -#define BBP_R77_PAIR FIELD8(0x03) +#define BBP_R77_RX_ANTENNA FIELD8(0x03) /* * RF registers @@ -1240,8 +1246,8 @@ struct hw_pairwise_ta_entry { /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 16 * sizeof(struct data_desc) ) -#define RXD_DESC_SIZE ( 16 * sizeof(struct data_desc) ) +#define TXD_DESC_SIZE ( 16 * sizeof(__le32) ) +#define RXD_DESC_SIZE ( 16 * sizeof(__le32) ) /* * TX descriptor format for TX, PRIO and Beacon Ring. diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index c0671c2..8093a4d 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -24,11 +24,6 @@ Supported chipsets: rt2571W & rt2671. */ -/* - * Set enviroment defines for rt2x00.h - */ -#define DRV_NAME "rt73usb" - #include #include #include @@ -52,8 +47,9 @@ * between each attampt. When the busy bit is still set at that time, * the access attempt is considered to have failed, * and we will print an error. + * The _lock versions must be used if you already hold the usb_cache_mutex */ -static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev, +static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 *value) { __le32 reg; @@ -63,8 +59,17 @@ static inline void rt73usb_register_read(const struct rt2x00_dev *rt2x00dev, *value = le32_to_cpu(reg); } -static inline void rt73usb_register_multiread(const struct rt2x00_dev - *rt2x00dev, +static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, u32 *value) +{ + __le32 reg; + rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, + USB_VENDOR_REQUEST_IN, offset, + ®, sizeof(u32), REGISTER_TIMEOUT); + *value = le32_to_cpu(reg); +} + +static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev, const unsigned int offset, void *value, const u32 length) { @@ -74,7 +79,7 @@ static inline void rt73usb_register_multiread(const struct rt2x00_dev value, length, timeout); } -static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev, +static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev, const unsigned int offset, u32 value) { __le32 reg = cpu_to_le32(value); @@ -83,8 +88,16 @@ static inline void rt73usb_register_write(const struct rt2x00_dev *rt2x00dev, ®, sizeof(u32), REGISTER_TIMEOUT); } -static inline void rt73usb_register_multiwrite(const struct rt2x00_dev - *rt2x00dev, +static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev, + const unsigned int offset, u32 value) +{ + __le32 reg = cpu_to_le32(value); + rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, + USB_VENDOR_REQUEST_OUT, offset, + ®, sizeof(u32), REGISTER_TIMEOUT); +} + +static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, const unsigned int offset, void *value, const u32 length) { @@ -94,13 +107,13 @@ static inline void rt73usb_register_multiwrite(const struct rt2x00_dev value, length, timeout); } -static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev) +static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev) { u32 reg; unsigned int i; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt73usb_register_read(rt2x00dev, PHY_CSR3, ®); + rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, ®); if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) break; udelay(REGISTER_BUSY_DELAY); @@ -109,17 +122,20 @@ static u32 rt73usb_bbp_check(const struct rt2x00_dev *rt2x00dev) return reg; } -static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev, +static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u8 value) { u32 reg; + mutex_lock(&rt2x00dev->usb_cache_mutex); + /* * Wait until the BBP becomes ready. */ reg = rt73usb_bbp_check(rt2x00dev); if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); return; } @@ -132,20 +148,24 @@ static void rt73usb_bbp_write(const struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); - rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); + rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); + mutex_unlock(&rt2x00dev->usb_cache_mutex); } -static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev, +static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, const unsigned int word, u8 *value) { u32 reg; + mutex_lock(&rt2x00dev->usb_cache_mutex); + /* * Wait until the BBP becomes ready. */ reg = rt73usb_bbp_check(rt2x00dev); if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); + mutex_unlock(&rt2x00dev->usb_cache_mutex); return; } @@ -157,7 +177,7 @@ static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); - rt73usb_register_write(rt2x00dev, PHY_CSR3, reg); + rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); /* * Wait until the BBP becomes ready. @@ -170,9 +190,10 @@ static void rt73usb_bbp_read(const struct rt2x00_dev *rt2x00dev, } *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); + mutex_unlock(&rt2x00dev->usb_cache_mutex); } -static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev, +static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, const unsigned int word, const u32 value) { u32 reg; @@ -181,13 +202,16 @@ static void rt73usb_rf_write(const struct rt2x00_dev *rt2x00dev, if (!word) return; + mutex_lock(&rt2x00dev->usb_cache_mutex); + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt73usb_register_read(rt2x00dev, PHY_CSR4, ®); + rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®); if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) goto rf_write; udelay(REGISTER_BUSY_DELAY); } + mutex_unlock(&rt2x00dev->usb_cache_mutex); ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); return; @@ -200,25 +224,26 @@ rf_write: * all others contain 20 bits. */ rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, - 20 + !!(rt2x00_rf(&rt2x00dev->chip, RF5225) || - rt2x00_rf(&rt2x00dev->chip, RF2527))); + 20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) || + rt2x00_rf(&rt2x00dev->chip, RF2527))); rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); - rt73usb_register_write(rt2x00dev, PHY_CSR4, reg); + rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg); rt2x00_rf_write(rt2x00dev, word, value); + mutex_unlock(&rt2x00dev->usb_cache_mutex); } #ifdef CONFIG_RT2X00_LIB_DEBUGFS #define CSR_OFFSET(__word) ( CSR_REG_BASE + ((__word) * sizeof(u32)) ) -static void rt73usb_read_csr(const struct rt2x00_dev *rt2x00dev, +static void rt73usb_read_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 *data) { rt73usb_register_read(rt2x00dev, CSR_OFFSET(word), data); } -static void rt73usb_write_csr(const struct rt2x00_dev *rt2x00dev, +static void rt73usb_write_csr(struct rt2x00_dev *rt2x00dev, const unsigned int word, u32 data) { rt73usb_register_write(rt2x00dev, CSR_OFFSET(word), data); @@ -396,12 +421,12 @@ static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev, } static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, - const int antenna_rx) + struct antenna_setup *ant) { u8 r3; u8 r4; u8 r77; + u8 temp; rt73usb_bbp_read(rt2x00dev, 3, &r3); rt73usb_bbp_read(rt2x00dev, 4, &r4); @@ -409,30 +434,38 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + /* + * Configure the RX antenna. + */ + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); - rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !!(rt2x00dev->curr_hwmode != HWMODE_A)); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); + temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags) + && (rt2x00dev->curr_hwmode != HWMODE_A); + rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); break; case ANTENNA_A: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); - if (rt2x00dev->curr_hwmode == HWMODE_A) - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); else - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0); - if (rt2x00dev->curr_hwmode == HWMODE_A) - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); else - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); break; } @@ -442,8 +475,7 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, } static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, - const int antenna_rx) + struct antenna_setup *ant) { u8 r3; u8 r4; @@ -457,18 +489,27 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)); - switch (antenna_rx) { - case ANTENNA_SW_DIVERSITY: + /* + * Configure the RX antenna. + */ + switch (ant->rx) { case ANTENNA_HW_DIVERSITY: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); break; case ANTENNA_A: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt2x00_set_field8(&r77, BBP_R77_PAIR, 3); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 3); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); break; + case ANTENNA_SW_DIVERSITY: + /* + * NOTE: We should never come here because rt2x00lib is + * supposed to catch this and send us the correct antenna + * explicitely. However we are nog going to bug about this. + * Instead, just default to antenna B. + */ case ANTENNA_B: - rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1); - rt2x00_set_field8(&r77, BBP_R77_PAIR, 0); + rt2x00_set_field8(&r77, BBP_R77_RX_ANTENNA, 0); + rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 1); break; } @@ -509,40 +550,40 @@ static const struct antenna_sel antenna_sel_bg[] = { }; static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev, - const int antenna_tx, const int antenna_rx) + struct antenna_setup *ant) { const struct antenna_sel *sel; unsigned int lna; unsigned int i; u32 reg; - rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); - if (rt2x00dev->curr_hwmode == HWMODE_A) { sel = antenna_sel_a; lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags); - - rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 0); - rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 1); } else { sel = antenna_sel_bg; lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags); - - rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, 1); - rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, 0); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]); + rt73usb_register_read(rt2x00dev, PHY_CSR0, ®); + + rt2x00_set_field32(®, PHY_CSR0_PA_PE_BG, + (rt2x00dev->curr_hwmode == HWMODE_B || + rt2x00dev->curr_hwmode == HWMODE_G)); + rt2x00_set_field32(®, PHY_CSR0_PA_PE_A, + (rt2x00dev->curr_hwmode == HWMODE_A)); + rt73usb_register_write(rt2x00dev, PHY_CSR0, reg); if (rt2x00_rf(&rt2x00dev->chip, RF5226) || rt2x00_rf(&rt2x00dev->chip, RF5225)) - rt73usb_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx); + rt73usb_config_antenna_5x(rt2x00dev, ant); else if (rt2x00_rf(&rt2x00dev->chip, RF2528) || rt2x00_rf(&rt2x00dev->chip, RF2527)) - rt73usb_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx); + rt73usb_config_antenna_2x(rt2x00dev, ant); } static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev, @@ -586,8 +627,7 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev, if ((flags & CONFIG_UPDATE_TXPOWER) && !(flags & CONFIG_UPDATE_CHANNEL)) rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level); if (flags & CONFIG_UPDATE_ANTENNA) - rt73usb_config_antenna(rt2x00dev, libconf->conf->antenna_sel_tx, - libconf->conf->antenna_sel_rx); + rt73usb_config_antenna(rt2x00dev, &libconf->ant); if (flags & (CONFIG_UPDATE_SLOT_TIME | CONFIG_UPDATE_BEACON_INT)) rt73usb_config_duration(rt2x00dev, libconf); } @@ -605,12 +645,10 @@ static void rt73usb_enable_led(struct rt2x00_dev *rt2x00dev) rt73usb_register_write(rt2x00dev, MAC_CSR14, reg); rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_RADIO_STATUS, 1); - if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) - rt2x00_set_field16(&rt2x00dev->led_reg, - MCU_LEDCS_LINK_A_STATUS, 1); - else - rt2x00_set_field16(&rt2x00dev->led_reg, - MCU_LEDCS_LINK_BG_STATUS, 1); + rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_A_STATUS, + (rt2x00dev->rx_status.phymode == MODE_IEEE80211A)); + rt2x00_set_field16(&rt2x00dev->led_reg, MCU_LEDCS_LINK_BG_STATUS, + (rt2x00dev->rx_status.phymode != MODE_IEEE80211A)); rt2x00usb_vendor_request_sw(rt2x00dev, USB_LED_CONTROL, 0x0000, rt2x00dev->led_reg, REGISTER_TIMEOUT); @@ -659,7 +697,8 @@ static void rt73usb_activity_led(struct rt2x00_dev *rt2x00dev, int rssi) /* * Link tuning */ -static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev) +static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, + struct link_qual *qual) { u32 reg; @@ -667,15 +706,13 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev) * Update FCS error count from register. */ rt73usb_register_read(rt2x00dev, STA_CSR0, ®); - rt2x00dev->link.rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); + qual->rx_failed = rt2x00_get_field32(reg, STA_CSR0_FCS_ERROR); /* * Update False CCA count from register. */ rt73usb_register_read(rt2x00dev, STA_CSR1, ®); - reg = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); - rt2x00dev->link.false_cca = - rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); + qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); } static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev) @@ -781,12 +818,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) * r17 does not yet exceed upper limit, continue and base * the r17 tuning on the false CCA count. */ - if (rt2x00dev->link.false_cca > 512 && r17 < up_bound) { + if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { r17 += 4; if (r17 > up_bound) r17 = up_bound; rt73usb_bbp_write(rt2x00dev, 17, r17); - } else if (rt2x00dev->link.false_cca < 100 && r17 > low_bound) { + } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { r17 -= 4; if (r17 < low_bound) r17 = low_bound; @@ -1193,7 +1230,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, * TX descriptor initialization */ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct data_desc *txd, + __le32 *txd, struct txdata_entry_desc *desc, struct ieee80211_hdr *ieee80211hdr, unsigned int length, @@ -1233,7 +1270,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_MORE_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_ACK, - !(control->flags & IEEE80211_TXCTL_NO_ACK)); + test_bit(ENTRY_TXD_ACK, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_TIMESTAMP, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags)); rt2x00_set_field32(&word, TXD_W0_OFDM, @@ -1340,7 +1377,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) static void rt73usb_fill_rxdone(struct data_entry *entry, struct rxdata_entry_desc *desc) { - struct data_desc *rxd = (struct data_desc *)entry->skb->data; + __le32 *rxd = (__le32 *)entry->skb->data; u32 word0; u32 word1; @@ -1392,8 +1429,10 @@ static int rt73usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); if (word == 0xffff) { rt2x00_set_field16(&word, EEPROM_ANTENNA_NUM, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, 2); - rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, 2); + rt2x00_set_field16(&word, EEPROM_ANTENNA_TX_DEFAULT, + ANTENNA_B); + rt2x00_set_field16(&word, EEPROM_ANTENNA_RX_DEFAULT, + ANTENNA_B); rt2x00_set_field16(&word, EEPROM_ANTENNA_FRAME_TYPE, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_DYN_TXAGC, 0); rt2x00_set_field16(&word, EEPROM_ANTENNA_HARDWARE_RADIO, 0); @@ -1502,9 +1541,9 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Identify default antenna configuration. */ - rt2x00dev->hw->conf.antenna_sel_tx = + rt2x00dev->default_ant.tx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TX_DEFAULT); - rt2x00dev->hw->conf.antenna_sel_rx = + rt2x00dev->default_ant.rx = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_DEFAULT); /* @@ -1926,6 +1965,9 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_tx_control *control) { struct rt2x00_dev *rt2x00dev = hw->priv; + struct skb_desc *desc; + struct data_ring *ring; + struct data_entry *entry; int timeout; /* @@ -1934,17 +1976,27 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, * initialization. */ control->queue = IEEE80211_TX_QUEUE_BEACON; + ring = rt2x00lib_get_ring(rt2x00dev, control->queue); + entry = rt2x00_get_data_entry(ring); + + /* + * Add the descriptor in front of the skb. + */ + skb_push(skb, ring->desc_size); + memset(skb->data, 0, ring->desc_size); /* - * First we create the beacon. + * Fill in skb descriptor */ - skb_push(skb, TXD_DESC_SIZE); - memset(skb->data, 0, TXD_DESC_SIZE); + desc = get_skb_desc(skb); + desc->desc_len = ring->desc_size; + desc->data_len = skb->len - ring->desc_size; + desc->desc = skb->data; + desc->data = skb->data + ring->desc_size; + desc->ring = ring; + desc->entry = entry; - rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data, - (struct ieee80211_hdr *)(skb->data + - TXD_DESC_SIZE), - skb->len - TXD_DESC_SIZE, control); + rt2x00lib_write_tx_desc(rt2x00dev, skb, control); /* * Write entire beacon with descriptor to register, @@ -2002,7 +2054,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { }; static const struct rt2x00_ops rt73usb_ops = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .rxd_size = RXD_DESC_SIZE, .txd_size = TXD_DESC_SIZE, .eeprom_size = EEPROM_SIZE, @@ -2089,7 +2141,7 @@ MODULE_FIRMWARE(FIRMWARE_RT2571); MODULE_LICENSE("GPL"); static struct usb_driver rt73usb_driver = { - .name = DRV_NAME, + .name = KBUILD_MODNAME, .id_table = rt73usb_device_table, .probe = rt2x00usb_probe, .disconnect = rt2x00usb_disconnect, diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index f095151..d49dcaa 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -713,13 +713,19 @@ struct hw_pairwise_ta_entry { * R4: RX antenna control * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529) */ -#define BBP_R4_RX_ANTENNA FIELD8(0x03) + +/* + * ANTENNA_CONTROL semantics (guessed): + * 0x1: Software controlled antenna switching (fixed or SW diversity) + * 0x2: Hardware diversity. + */ +#define BBP_R4_RX_ANTENNA_CONTROL FIELD8(0x03) #define BBP_R4_RX_FRAME_END FIELD8(0x20) /* * R77 */ -#define BBP_R77_PAIR FIELD8(0x03) +#define BBP_R77_RX_ANTENNA FIELD8(0x03) /* * RF registers @@ -860,8 +866,8 @@ struct hw_pairwise_ta_entry { /* * DMA descriptor defines. */ -#define TXD_DESC_SIZE ( 6 * sizeof(struct data_desc) ) -#define RXD_DESC_SIZE ( 6 * sizeof(struct data_desc) ) +#define TXD_DESC_SIZE ( 6 * sizeof(__le32) ) +#define RXD_DESC_SIZE ( 6 * sizeof(__le32) ) /* * TX descriptor format for TX, PRIO and Beacon Ring. diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index e454ae8..bd1ab3b 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -38,6 +38,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x6a00)}, /* HP */ {USB_DEVICE(0x03f0, 0xca02)}, + /* Sitecom */ + {USB_DEVICE(0x0df6, 0x000d)}, {} }; diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index efc4120..eade81f 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c @@ -283,8 +283,8 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) u32 reg; int i; - cck_power = priv->channels[channel - 1].val & 0xF; - ofdm_power = priv->channels[channel - 1].val >> 4; + cck_power = priv->channels[channel - 1].val & 0xFF; + ofdm_power = priv->channels[channel - 1].val >> 8; cck_power = min(cck_power, (u8)11); ofdm_power = min(ofdm_power, (u8)35); @@ -500,8 +500,8 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) u32 reg; int i; - cck_power = priv->channels[channel - 1].val & 0xF; - ofdm_power = priv->channels[channel - 1].val >> 4; + cck_power = priv->channels[channel - 1].val & 0xFF; + ofdm_power = priv->channels[channel - 1].val >> 8; cck_power = min(cck_power, (u8)15); cck_power += priv->txpwr_base & 0xF; diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index a1f8a16..b343ce2 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c @@ -3740,7 +3740,7 @@ static int wv_check_ioaddr(unsigned long ioaddr, u8 * mac) * non-NCR/AT&T/Lucent ISA card. See wavelan.p.h for detail on * how to configure your card. */ - for (i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++) + for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++) if ((mac[0] == MAC_ADDRESSES[i][0]) && (mac[1] == MAC_ADDRESSES[i][1]) && (mac[2] == MAC_ADDRESSES[i][2])) diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 577c647..da1d4e8 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -3223,14 +3223,14 @@ wv_mmc_init(struct net_device * dev) * non-NCR/AT&T/Lucent PCMCIA cards, see wavelan_cs.h for detail on * how to configure your card... */ - for(i = 0; i < (sizeof(MAC_ADDRESSES) / sizeof(char) / 3); i++) - if((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) && - (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) && - (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2])) + for (i = 0; i < ARRAY_SIZE(MAC_ADDRESSES); i++) + if ((psa.psa_univ_mac_addr[0] == MAC_ADDRESSES[i][0]) && + (psa.psa_univ_mac_addr[1] == MAC_ADDRESSES[i][1]) && + (psa.psa_univ_mac_addr[2] == MAC_ADDRESSES[i][2])) break; /* If we have not found it... */ - if(i == (sizeof(MAC_ADDRESSES) / sizeof(char) / 3)) + if (i == ARRAY_SIZE(MAC_ADDRESSES)) { #ifdef DEBUG_CONFIG_ERRORS printk(KERN_WARNING "%s: wv_mmc_init(): Invalid MAC address: %02X:%02X:%02X:...\n", diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig index d1ab24a..74b31ea 100644 --- a/drivers/net/wireless/zd1211rw/Kconfig +++ b/drivers/net/wireless/zd1211rw/Kconfig @@ -1,14 +1,13 @@ config ZD1211RW tristate "ZyDAS ZD1211/ZD1211B USB-wireless support" - depends on USB && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL - select WIRELESS_EXT + depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL select FW_LOADER ---help--- This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless chip, present in many USB-wireless adapters. - Device firmware is required alongside this driver. You can download the - firmware distribution from http://zd1211.ath.cx/get-firmware + Device firmware is required alongside this driver. You can download + the firmware distribution from http://zd1211.ath.cx/get-firmware config ZD1211RW_DEBUG bool "ZyDAS ZD1211 debugging" diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile index 7a2f2a9..cc36126 100644 --- a/drivers/net/wireless/zd1211rw/Makefile +++ b/drivers/net/wireless/zd1211rw/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_ZD1211RW) += zd1211rw.o -zd1211rw-objs := zd_chip.o zd_ieee80211.o \ - zd_mac.o zd_netdev.o \ +zd1211rw-objs := zd_chip.o zd_ieee80211.o zd_mac.o \ zd_rf_al2230.o zd_rf_rf2959.o \ zd_rf_al7230b.o zd_rf_uw2453.o \ zd_rf.o zd_usb.o diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index f831b68..99e5b03 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -1,4 +1,7 @@ -/* zd_chip.c +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -30,12 +33,12 @@ #include "zd_rf.h" void zd_chip_init(struct zd_chip *chip, - struct net_device *netdev, + struct ieee80211_hw *hw, struct usb_interface *intf) { memset(chip, 0, sizeof(*chip)); mutex_init(&chip->mutex); - zd_usb_init(&chip->usb, netdev, intf); + zd_usb_init(&chip->usb, hw, intf); zd_rf_init(&chip->rf); } @@ -50,7 +53,7 @@ void zd_chip_clear(struct zd_chip *chip) static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size) { - u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr; + u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip)); return scnprintf(buffer, size, "%02x-%02x-%02x", addr[0], addr[1], addr[2]); } @@ -378,15 +381,18 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) }; DECLARE_MAC_BUF(mac); - reqs[0].value = (mac_addr[3] << 24) - | (mac_addr[2] << 16) - | (mac_addr[1] << 8) - | mac_addr[0]; - reqs[1].value = (mac_addr[5] << 8) - | mac_addr[4]; - - dev_dbg_f(zd_chip_dev(chip), - "mac addr %s\n", print_mac(mac, mac_addr)); + if (mac_addr) { + reqs[0].value = (mac_addr[3] << 24) + | (mac_addr[2] << 16) + | (mac_addr[1] << 8) + | mac_addr[0]; + reqs[1].value = (mac_addr[5] << 8) + | mac_addr[4]; + dev_dbg_f(zd_chip_dev(chip), + "mac addr %s\n", print_mac(mac, mac_addr)); + } else { + dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n"); + } mutex_lock(&chip->mutex); r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); @@ -980,7 +986,7 @@ static int print_fw_version(struct zd_chip *chip) return 0; } -static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) +static int set_mandatory_rates(struct zd_chip *chip, int mode) { u32 rates; ZD_ASSERT(mutex_is_locked(&chip->mutex)); @@ -988,11 +994,11 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) * that the device is supporting. Until further notice we should try * to support 802.11g also for full speed USB. */ - switch (std) { - case IEEE80211B: + switch (mode) { + case MODE_IEEE80211B: rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; break; - case IEEE80211G: + case MODE_IEEE80211G: rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; break; @@ -1003,24 +1009,17 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) } int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, - u8 rts_rate, int preamble) + int preamble) { - int rts_mod = ZD_RX_CCK; u32 value = 0; - /* Modulation bit */ - if (ZD_MODULATION_TYPE(rts_rate) == ZD_OFDM) - rts_mod = ZD_RX_OFDM; - - dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n", - rts_rate, preamble); - - value |= ZD_PURE_RATE(rts_rate) << RTSCTS_SH_RTS_RATE; - value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE; + dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble); value |= preamble << RTSCTS_SH_RTS_PMB_TYPE; value |= preamble << RTSCTS_SH_CTS_PMB_TYPE; - /* We always send 11M self-CTS messages, like the vendor driver. */ + /* We always send 11M RTS/self-CTS messages, like the vendor driver. */ + value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE; + value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE; value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE; value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE; @@ -1109,7 +1108,7 @@ int zd_chip_init_hw(struct zd_chip *chip) * It might be discussed, whether we should suppport pure b mode for * full speed USB. */ - r = set_mandatory_rates(chip, IEEE80211G); + r = set_mandatory_rates(chip, MODE_IEEE80211G); if (r) goto out; /* Disabling interrupts is certainly a smart thing here. @@ -1320,12 +1319,17 @@ out: return r; } -int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates) +int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) { - ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0); - dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates); + int r; + + if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G)) + return -EINVAL; - return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); + mutex_lock(&chip->mutex); + r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); + mutex_unlock(&chip->mutex); + return r; } static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) @@ -1468,56 +1472,44 @@ u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, { return (status->frame_status&ZD_RX_OFDM) ? ofdm_qual_percent(status->signal_quality_ofdm, - zd_rate_from_ofdm_plcp_header(rx_frame), + zd_rate_from_ofdm_plcp_header(rx_frame), size) : cck_qual_percent(status->signal_quality_cck); } -u8 zd_rx_strength_percent(u8 rssi) -{ - int r = (rssi*100) / 41; - if (r > 100) - r = 100; - return (u8) r; -} - -u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status) +/** + * zd_rx_rate - report zd-rate + * @rx_frame - received frame + * @rx_status - rx_status as given by the device + * + * This function converts the rate as encoded in the received packet to the + * zd-rate, we are using on other places in the driver. + */ +u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status) { - static const u16 ofdm_rates[] = { - [ZD_OFDM_PLCP_RATE_6M] = 60, - [ZD_OFDM_PLCP_RATE_9M] = 90, - [ZD_OFDM_PLCP_RATE_12M] = 120, - [ZD_OFDM_PLCP_RATE_18M] = 180, - [ZD_OFDM_PLCP_RATE_24M] = 240, - [ZD_OFDM_PLCP_RATE_36M] = 360, - [ZD_OFDM_PLCP_RATE_48M] = 480, - [ZD_OFDM_PLCP_RATE_54M] = 540, - }; - u16 rate; + u8 zd_rate; if (status->frame_status & ZD_RX_OFDM) { - /* Deals with PLCP OFDM rate (not zd_rates) */ - u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame); - rate = ofdm_rates[ofdm_rate & 0xf]; + zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame); } else { switch (zd_cck_plcp_header_signal(rx_frame)) { case ZD_CCK_PLCP_SIGNAL_1M: - rate = 10; + zd_rate = ZD_CCK_RATE_1M; break; case ZD_CCK_PLCP_SIGNAL_2M: - rate = 20; + zd_rate = ZD_CCK_RATE_2M; break; case ZD_CCK_PLCP_SIGNAL_5M5: - rate = 55; + zd_rate = ZD_CCK_RATE_5_5M; break; case ZD_CCK_PLCP_SIGNAL_11M: - rate = 110; + zd_rate = ZD_CCK_RATE_11M; break; default: - rate = 0; + zd_rate = 0; } } - return rate; + return zd_rate; } int zd_chip_switch_radio_on(struct zd_chip *chip) @@ -1557,20 +1549,22 @@ void zd_chip_disable_int(struct zd_chip *chip) mutex_unlock(&chip->mutex); } -int zd_chip_enable_rx(struct zd_chip *chip) +int zd_chip_enable_rxtx(struct zd_chip *chip) { int r; mutex_lock(&chip->mutex); + zd_usb_enable_tx(&chip->usb); r = zd_usb_enable_rx(&chip->usb); mutex_unlock(&chip->mutex); return r; } -void zd_chip_disable_rx(struct zd_chip *chip) +void zd_chip_disable_rxtx(struct zd_chip *chip) { mutex_lock(&chip->mutex); zd_usb_disable_rx(&chip->usb); + zd_usb_disable_tx(&chip->usb); mutex_unlock(&chip->mutex); } diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 8009b70..009c037 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h @@ -1,4 +1,7 @@ -/* zd_chip.h +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -433,9 +436,10 @@ enum { #define CR_GROUP_HASH_P2 CTL_REG(0x0628) #define CR_RX_TIMEOUT CTL_REG(0x062C) + /* Basic rates supported by the BSS. When producing ACK or CTS messages, the * device will use a rate in this table that is less than or equal to the rate - * of the incoming frame which prompted the response */ + * of the incoming frame which prompted the response. */ #define CR_BASIC_RATE_TBL CTL_REG(0x0630) #define CR_RATE_1M (1 << 0) /* 802.11b */ #define CR_RATE_2M (1 << 1) /* 802.11b */ @@ -509,14 +513,37 @@ enum { #define CR_UNDERRUN_CNT CTL_REG(0x0688) #define CR_RX_FILTER CTL_REG(0x068c) +#define RX_FILTER_ASSOC_REQUEST (1 << 0) #define RX_FILTER_ASSOC_RESPONSE (1 << 1) +#define RX_FILTER_REASSOC_REQUEST (1 << 2) #define RX_FILTER_REASSOC_RESPONSE (1 << 3) +#define RX_FILTER_PROBE_REQUEST (1 << 4) #define RX_FILTER_PROBE_RESPONSE (1 << 5) +/* bits 6 and 7 reserved */ #define RX_FILTER_BEACON (1 << 8) +#define RX_FILTER_ATIM (1 << 9) #define RX_FILTER_DISASSOC (1 << 10) #define RX_FILTER_AUTH (1 << 11) -#define AP_RX_FILTER 0x0400feff -#define STA_RX_FILTER 0x0000ffff +#define RX_FILTER_DEAUTH (1 << 12) +#define RX_FILTER_PSPOLL (1 << 26) +#define RX_FILTER_RTS (1 << 27) +#define RX_FILTER_CTS (1 << 28) +#define RX_FILTER_ACK (1 << 29) +#define RX_FILTER_CFEND (1 << 30) +#define RX_FILTER_CFACK (1 << 31) + +/* Enable bits for all frames you are interested in. */ +#define STA_RX_FILTER (RX_FILTER_ASSOC_REQUEST | RX_FILTER_ASSOC_RESPONSE | \ + RX_FILTER_REASSOC_REQUEST | RX_FILTER_REASSOC_RESPONSE | \ + RX_FILTER_PROBE_REQUEST | RX_FILTER_PROBE_RESPONSE | \ + (0x3 << 6) /* vendor driver sets these reserved bits */ | \ + RX_FILTER_BEACON | RX_FILTER_ATIM | RX_FILTER_DISASSOC | \ + RX_FILTER_AUTH | RX_FILTER_DEAUTH | \ + (0x7 << 13) /* vendor driver sets these reserved bits */ | \ + RX_FILTER_PSPOLL | RX_FILTER_ACK) /* 0x2400ffff */ + +#define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ + RX_FILTER_CFEND | RX_FILTER_CFACK) /* Monitor mode sets filter to 0xfffff */ @@ -730,7 +757,7 @@ static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf) #define zd_chip_dev(chip) (&(chip)->usb.intf->dev) void zd_chip_init(struct zd_chip *chip, - struct net_device *netdev, + struct ieee80211_hw *hw, struct usb_interface *intf); void zd_chip_clear(struct zd_chip *chip); int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr); @@ -835,14 +862,12 @@ int zd_chip_switch_radio_on(struct zd_chip *chip); int zd_chip_switch_radio_off(struct zd_chip *chip); int zd_chip_enable_int(struct zd_chip *chip); void zd_chip_disable_int(struct zd_chip *chip); -int zd_chip_enable_rx(struct zd_chip *chip); -void zd_chip_disable_rx(struct zd_chip *chip); +int zd_chip_enable_rxtx(struct zd_chip *chip); +void zd_chip_disable_rxtx(struct zd_chip *chip); int zd_chip_enable_hwint(struct zd_chip *chip); int zd_chip_disable_hwint(struct zd_chip *chip); int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel); - -int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, - u8 rts_rate, int preamble); +int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, int preamble); static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) { @@ -859,17 +884,7 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates) return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); } -int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates); - -static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) -{ - int r; - - mutex_lock(&chip->mutex); - r = zd_chip_set_basic_rates_locked(chip, cr_rates); - mutex_unlock(&chip->mutex); - return r; -} +int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); int zd_chip_lock_phy_regs(struct zd_chip *chip); int zd_chip_unlock_phy_regs(struct zd_chip *chip); @@ -893,9 +908,8 @@ struct rx_status; u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, const struct rx_status *status); -u8 zd_rx_strength_percent(u8 rssi); -u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status); +u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); struct zd_mc_hash { u32 low; diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index 505b4d7..5200db4 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h @@ -1,4 +1,7 @@ -/* zd_def.h +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c index 189160e..7c277ec 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.c +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c @@ -1,4 +1,7 @@ -/* zd_ieee80211.c +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -16,178 +19,85 @@ */ /* - * A lot of this code is generic and should be moved into the upper layers - * at some point. + * In the long term, we'll probably find a better way of handling regulatory + * requirements outside of the driver. */ -#include -#include #include -#include +#include -#include "zd_def.h" #include "zd_ieee80211.h" #include "zd_mac.h" +struct channel_range { + u8 regdomain; + u8 start; + u8 end; /* exclusive (channel must be less than end) */ +}; + static const struct channel_range channel_ranges[] = { - [0] = { 0, 0}, - [ZD_REGDOMAIN_FCC] = { 1, 12}, - [ZD_REGDOMAIN_IC] = { 1, 12}, - [ZD_REGDOMAIN_ETSI] = { 1, 14}, - [ZD_REGDOMAIN_JAPAN] = { 1, 14}, - [ZD_REGDOMAIN_SPAIN] = { 1, 14}, - [ZD_REGDOMAIN_FRANCE] = { 1, 14}, + { ZD_REGDOMAIN_FCC, 1, 12 }, + { ZD_REGDOMAIN_IC, 1, 12 }, + { ZD_REGDOMAIN_ETSI, 1, 14 }, + { ZD_REGDOMAIN_JAPAN, 1, 14 }, + { ZD_REGDOMAIN_SPAIN, 1, 14 }, + { ZD_REGDOMAIN_FRANCE, 1, 14 }, /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in * 802.11). However, in 2001 the range was extended to include channels * 1-13. The ZyDAS devices still use the old region code but are * designed to allow the extra channel access in Japan. */ - [ZD_REGDOMAIN_JAPAN_ADD] = { 1, 15}, + { ZD_REGDOMAIN_JAPAN_ADD, 1, 15 }, }; -const struct channel_range *zd_channel_range(u8 regdomain) -{ - if (regdomain >= ARRAY_SIZE(channel_ranges)) - regdomain = 0; - return &channel_ranges[regdomain]; -} - -int zd_regdomain_supports_channel(u8 regdomain, u8 channel) -{ - const struct channel_range *range = zd_channel_range(regdomain); - return range->start <= channel && channel < range->end; -} - -int zd_regdomain_supported(u8 regdomain) -{ - const struct channel_range *range = zd_channel_range(regdomain); - return range->start != 0; -} - -/* Stores channel frequencies in MHz. */ -static const u16 channel_frequencies[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, 2472, 2484, -}; - -#define NUM_CHANNELS ARRAY_SIZE(channel_frequencies) - -static int compute_freq(struct iw_freq *freq, u32 mhz, u32 hz) -{ - u32 factor; - - freq->e = 0; - if (mhz >= 1000000000U) { - pr_debug("zd1211 mhz %u to large\n", mhz); - freq->m = 0; - return -EINVAL; - } - - factor = 1000; - while (mhz >= factor) { - - freq->e += 1; - factor *= 10; - } - - factor /= 1000U; - freq->m = mhz * (1000000U/factor) + hz/factor; - - return 0; -} - -int zd_channel_to_freq(struct iw_freq *freq, u8 channel) +static const struct channel_range *zd_channel_range(u8 regdomain) { - if (channel > NUM_CHANNELS) { - freq->m = 0; - freq->e = 0; - return -EINVAL; - } - if (!channel) { - freq->m = 0; - freq->e = 0; - return -EINVAL; + int i; + for (i = 0; i < ARRAY_SIZE(channel_ranges); i++) { + const struct channel_range *range = &channel_ranges[i]; + if (range->regdomain == regdomain) + return range; } - return compute_freq(freq, channel_frequencies[channel-1], 0); + return NULL; } -static int freq_to_mhz(const struct iw_freq *freq) -{ - u32 factor; - int e; - - /* Such high frequencies are not supported. */ - if (freq->e > 6) - return -EINVAL; - - factor = 1; - for (e = freq->e; e > 0; --e) { - factor *= 10; - } - factor = 1000000U / factor; - - if (freq->m % factor) { - return -EINVAL; - } - - return freq->m / factor; -} +#define CHAN_TO_IDX(chan) ((chan) - 1) -int zd_find_channel(u8 *channel, const struct iw_freq *freq) +static void unmask_bg_channels(struct ieee80211_hw *hw, + const struct channel_range *range, + struct ieee80211_hw_mode *mode) { - int i, r; - u32 mhz; - - if (freq->m < 1000) { - if (freq->m > NUM_CHANNELS || freq->m == 0) - return -EINVAL; - *channel = freq->m; - return 1; - } - - r = freq_to_mhz(freq); - if (r < 0) - return r; - mhz = r; + u8 channel; - for (i = 0; i < NUM_CHANNELS; i++) { - if (mhz == channel_frequencies[i]) { - *channel = i+1; - return 1; - } + for (channel = range->start; channel < range->end; channel++) { + struct ieee80211_channel *chan = + &mode->channels[CHAN_TO_IDX(channel)]; + chan->flag |= IEEE80211_CHAN_W_SCAN | + IEEE80211_CHAN_W_ACTIVE_SCAN | + IEEE80211_CHAN_W_IBSS; } - - return -EINVAL; } -int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain) +void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain) { - struct ieee80211_geo geo; + struct zd_mac *mac = zd_hw_mac(hw); const struct channel_range *range; - int i; - u8 channel; - dev_dbg(zd_mac_dev(zd_netdev_mac(ieee->dev)), - "regdomain %#04x\n", regdomain); + dev_dbg(zd_mac_dev(mac), "regdomain %#02x\n", regdomain); range = zd_channel_range(regdomain); - if (range->start == 0) { - dev_err(zd_mac_dev(zd_netdev_mac(ieee->dev)), - "zd1211 regdomain %#04x not supported\n", - regdomain); - return -EINVAL; + if (!range) { + /* The vendor driver overrides the regulatory domain and + * allowed channel registers and unconditionally restricts + * available channels to 1-11 everywhere. Match their + * questionable behaviour only for regdomains which we don't + * recognise. */ + dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: " + "%#02x. Defaulting to FCC.\n", regdomain); + range = zd_channel_range(ZD_REGDOMAIN_FCC); } - memset(&geo, 0, sizeof(geo)); - - for (i = 0, channel = range->start; channel < range->end; channel++) { - struct ieee80211_channel *chan = &geo.bg[i++]; - chan->freq = channel_frequencies[channel - 1]; - chan->channel = channel; - } - - geo.bg_channels = i; - memcpy(geo.name, "XX ", 4); - ieee80211_set_geo(ieee, &geo); - return 0; + unmask_bg_channels(hw, range, &mac->modes[0]); + unmask_bg_channels(hw, range, &mac->modes[1]); } + diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h index fbf6491..26b79f1 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h @@ -1,7 +1,27 @@ +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake + * + * 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 + */ + #ifndef _ZD_IEEE80211_H #define _ZD_IEEE80211_H -#include +#include /* Additional definitions from the standards. */ @@ -19,22 +39,7 @@ enum { MAX_CHANNEL24 = 14, }; -struct channel_range { - u8 start; - u8 end; /* exclusive (channel must be less than end) */ -}; - -struct iw_freq; - -int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain); - -const struct channel_range *zd_channel_range(u8 regdomain); -int zd_regdomain_supports_channel(u8 regdomain, u8 channel); -int zd_regdomain_supported(u8 regdomain); - -/* for 2.4 GHz band */ -int zd_channel_to_freq(struct iw_freq *freq, u8 channel); -int zd_find_channel(u8 *channel, const struct iw_freq *freq); +void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain); #define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80 @@ -54,8 +59,8 @@ static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header) * * See the struct zd_ctrlset definition in zd_mac.h. */ -#define ZD_OFDM_PLCP_RATE_6M 0xb -#define ZD_OFDM_PLCP_RATE_9M 0xf +#define ZD_OFDM_PLCP_RATE_6M 0xb +#define ZD_OFDM_PLCP_RATE_9M 0xf #define ZD_OFDM_PLCP_RATE_12M 0xa #define ZD_OFDM_PLCP_RATE_18M 0xe #define ZD_OFDM_PLCP_RATE_24M 0x9 @@ -87,10 +92,4 @@ static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header) #define ZD_CCK_PLCP_SIGNAL_5M5 0x37 #define ZD_CCK_PLCP_SIGNAL_11M 0x6e -enum ieee80211_std { - IEEE80211B = 0x01, - IEEE80211A = 0x02, - IEEE80211G = 0x04, -}; - #endif /* _ZD_IEEE80211_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a903645..14fb727 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -1,4 +1,9 @@ -/* zd_mac.c +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake + * Copyright (C) 2006-2007 Michael Wu + * Copyright (c) 2007 Luis R. Rodriguez * * 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 @@ -17,7 +22,6 @@ #include #include -#include #include #include #include @@ -26,81 +30,105 @@ #include "zd_chip.h" #include "zd_mac.h" #include "zd_ieee80211.h" -#include "zd_netdev.h" #include "zd_rf.h" -static void ieee_init(struct ieee80211_device *ieee); -static void softmac_init(struct ieee80211softmac_device *sm); -static void set_rts_cts_work(struct work_struct *work); -static void set_basic_rates_work(struct work_struct *work); +/* This table contains the hardware specific values for the modulation rates. */ +static const struct ieee80211_rate zd_rates[] = { + { .rate = 10, + .val = ZD_CCK_RATE_1M, + .flags = IEEE80211_RATE_CCK }, + { .rate = 20, + .val = ZD_CCK_RATE_2M, + .val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_CCK_2 }, + { .rate = 55, + .val = ZD_CCK_RATE_5_5M, + .val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_CCK_2 }, + { .rate = 110, + .val = ZD_CCK_RATE_11M, + .val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, + .flags = IEEE80211_RATE_CCK_2 }, + { .rate = 60, + .val = ZD_OFDM_RATE_6M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 90, + .val = ZD_OFDM_RATE_9M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 120, + .val = ZD_OFDM_RATE_12M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 180, + .val = ZD_OFDM_RATE_18M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 240, + .val = ZD_OFDM_RATE_24M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 360, + .val = ZD_OFDM_RATE_36M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 480, + .val = ZD_OFDM_RATE_48M, + .flags = IEEE80211_RATE_OFDM }, + { .rate = 540, + .val = ZD_OFDM_RATE_54M, + .flags = IEEE80211_RATE_OFDM }, +}; + +static const struct ieee80211_channel zd_channels[] = { + { .chan = 1, + .freq = 2412}, + { .chan = 2, + .freq = 2417}, + { .chan = 3, + .freq = 2422}, + { .chan = 4, + .freq = 2427}, + { .chan = 5, + .freq = 2432}, + { .chan = 6, + .freq = 2437}, + { .chan = 7, + .freq = 2442}, + { .chan = 8, + .freq = 2447}, + { .chan = 9, + .freq = 2452}, + { .chan = 10, + .freq = 2457}, + { .chan = 11, + .freq = 2462}, + { .chan = 12, + .freq = 2467}, + { .chan = 13, + .freq = 2472}, + { .chan = 14, + .freq = 2484} +}; static void housekeeping_init(struct zd_mac *mac); static void housekeeping_enable(struct zd_mac *mac); static void housekeeping_disable(struct zd_mac *mac); -static void set_multicast_hash_handler(struct work_struct *work); - -static void do_rx(unsigned long mac_ptr); - -int zd_mac_init(struct zd_mac *mac, - struct net_device *netdev, - struct usb_interface *intf) -{ - struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev); - - memset(mac, 0, sizeof(*mac)); - spin_lock_init(&mac->lock); - mac->netdev = netdev; - INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); - INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); - - skb_queue_head_init(&mac->rx_queue); - tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); - tasklet_disable(&mac->rx_tasklet); - - ieee_init(ieee); - softmac_init(ieee80211_priv(netdev)); - zd_chip_init(&mac->chip, netdev, intf); - housekeeping_init(mac); - INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); - return 0; -} - -static int reset_channel(struct zd_mac *mac) -{ - int r; - unsigned long flags; - const struct channel_range *range; - - spin_lock_irqsave(&mac->lock, flags); - range = zd_channel_range(mac->regdomain); - if (!range->start) { - r = -EINVAL; - goto out; - } - mac->requested_channel = range->start; - r = 0; -out: - spin_unlock_irqrestore(&mac->lock, flags); - return r; -} - -int zd_mac_preinit_hw(struct zd_mac *mac) +int zd_mac_preinit_hw(struct ieee80211_hw *hw) { int r; u8 addr[ETH_ALEN]; + struct zd_mac *mac = zd_hw_mac(hw); r = zd_chip_read_mac_addr_fw(&mac->chip, addr); if (r) return r; - memcpy(mac->netdev->dev_addr, addr, ETH_ALEN); + SET_IEEE80211_PERM_ADDR(hw, addr); + return 0; } -int zd_mac_init_hw(struct zd_mac *mac) +int zd_mac_init_hw(struct ieee80211_hw *hw) { int r; + struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; u8 default_regdomain; @@ -116,22 +144,9 @@ int zd_mac_init_hw(struct zd_mac *mac) r = zd_read_regdomain(chip, &default_regdomain); if (r) goto disable_int; - if (!zd_regdomain_supported(default_regdomain)) { - /* The vendor driver overrides the regulatory domain and - * allowed channel registers and unconditionally restricts - * available channels to 1-11 everywhere. Match their - * questionable behaviour only for regdomains which we don't - * recognise. */ - dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: " - "%#04x. Defaulting to FCC.\n", default_regdomain); - default_regdomain = ZD_REGDOMAIN_FCC; - } spin_lock_irq(&mac->lock); mac->regdomain = mac->default_regdomain = default_regdomain; spin_unlock_irq(&mac->lock); - r = reset_channel(mac); - if (r) - goto disable_int; /* We must inform the device that we are doing encryption/decryption in * software at the moment. */ @@ -139,9 +154,7 @@ int zd_mac_init_hw(struct zd_mac *mac) if (r) goto disable_int; - r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain); - if (r) - goto disable_int; + zd_geo_init(hw, mac->regdomain); r = 0; disable_int: @@ -153,8 +166,6 @@ out: void zd_mac_clear(struct zd_mac *mac) { flush_workqueue(zd_workqueue); - skb_queue_purge(&mac->rx_queue); - tasklet_kill(&mac->rx_tasklet); zd_chip_clear(&mac->chip); ZD_ASSERT(!spin_is_locked(&mac->lock)); ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); @@ -162,34 +173,27 @@ void zd_mac_clear(struct zd_mac *mac) static int set_rx_filter(struct zd_mac *mac) { - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER; - return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); -} + unsigned long flags; + u32 filter = STA_RX_FILTER; -static int set_sniffer(struct zd_mac *mac) -{ - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - return zd_iowrite32(&mac->chip, CR_SNIFFER_ON, - ieee->iw_mode == IW_MODE_MONITOR ? 1 : 0); - return 0; + spin_lock_irqsave(&mac->lock, flags); + if (mac->pass_ctrl) + filter |= RX_FILTER_CTRL; + spin_unlock_irqrestore(&mac->lock, flags); + + return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); } static int set_mc_hash(struct zd_mac *mac) { struct zd_mc_hash hash; - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - zd_mc_clear(&hash); - if (ieee->iw_mode == IW_MODE_MONITOR) - zd_mc_add_all(&hash); - return zd_chip_set_multicast_hash(&mac->chip, &hash); } -int zd_mac_open(struct net_device *netdev) +static int zd_op_start(struct ieee80211_hw *hw) { - struct zd_mac *mac = zd_netdev_mac(netdev); + struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; struct zd_usb *usb = &chip->usb; int r; @@ -200,46 +204,33 @@ int zd_mac_open(struct net_device *netdev) goto out; } - tasklet_enable(&mac->rx_tasklet); - r = zd_chip_enable_int(chip); if (r < 0) goto out; - r = zd_write_mac_addr(chip, netdev->dev_addr); - if (r) - goto disable_int; - r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); if (r < 0) goto disable_int; r = set_rx_filter(mac); if (r) goto disable_int; - r = set_sniffer(mac); - if (r) - goto disable_int; r = set_mc_hash(mac); if (r) goto disable_int; r = zd_chip_switch_radio_on(chip); if (r < 0) goto disable_int; - r = zd_chip_set_channel(chip, mac->requested_channel); - if (r < 0) - goto disable_radio; - r = zd_chip_enable_rx(chip); + r = zd_chip_enable_rxtx(chip); if (r < 0) goto disable_radio; r = zd_chip_enable_hwint(chip); if (r < 0) - goto disable_rx; + goto disable_rxtx; housekeeping_enable(mac); - ieee80211softmac_start(netdev); return 0; -disable_rx: - zd_chip_disable_rx(chip); +disable_rxtx: + zd_chip_disable_rxtx(chip); disable_radio: zd_chip_switch_radio_off(chip); disable_int: @@ -248,494 +239,190 @@ out: return r; } -int zd_mac_stop(struct net_device *netdev) +/** + * clear_tx_skb_control_block - clears the control block of tx skbuffs + * @skb: a &struct sk_buff pointer + * + * This clears the control block of skbuff buffers, which were transmitted to + * the device. Notify that the function is not thread-safe, so prevent + * multiple calls. + */ +static void clear_tx_skb_control_block(struct sk_buff *skb) +{ + struct zd_tx_skb_control_block *cb = + (struct zd_tx_skb_control_block *)skb->cb; + + kfree(cb->control); + cb->control = NULL; +} + +/** + * kfree_tx_skb - frees a tx skbuff + * @skb: a &struct sk_buff pointer + * + * Frees the tx skbuff. Frees also the allocated control structure in the + * control block if necessary. + */ +static void kfree_tx_skb(struct sk_buff *skb) { - struct zd_mac *mac = zd_netdev_mac(netdev); - struct zd_chip *chip = &mac->chip; + clear_tx_skb_control_block(skb); + dev_kfree_skb_any(skb); +} - netif_stop_queue(netdev); +static void zd_op_stop(struct ieee80211_hw *hw) +{ + struct zd_mac *mac = zd_hw_mac(hw); + struct zd_chip *chip = &mac->chip; + struct sk_buff *skb; + struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; - /* - * The order here deliberately is a little different from the open() + /* The order here deliberately is a little different from the open() * method, since we need to make sure there is no opportunity for RX - * frames to be processed by softmac after we have stopped it. + * frames to be processed by mac80211 after we have stopped it. */ - zd_chip_disable_rx(chip); - skb_queue_purge(&mac->rx_queue); - tasklet_disable(&mac->rx_tasklet); + zd_chip_disable_rxtx(chip); housekeeping_disable(mac); - ieee80211softmac_stop(netdev); - - /* Ensure no work items are running or queued from this point */ - cancel_delayed_work(&mac->set_rts_cts_work); - cancel_delayed_work(&mac->set_basic_rates_work); flush_workqueue(zd_workqueue); - mac->updating_rts_rate = 0; - mac->updating_basic_rates = 0; zd_chip_disable_hwint(chip); zd_chip_switch_radio_off(chip); zd_chip_disable_int(chip); - return 0; -} - -int zd_mac_set_mac_address(struct net_device *netdev, void *p) -{ - int r; - unsigned long flags; - struct sockaddr *addr = p; - struct zd_mac *mac = zd_netdev_mac(netdev); - struct zd_chip *chip = &mac->chip; - DECLARE_MAC_BUF(mac2); - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - dev_dbg_f(zd_mac_dev(mac), - "Setting MAC to %s\n", print_mac(mac2, addr->sa_data)); - - if (netdev->flags & IFF_UP) { - r = zd_write_mac_addr(chip, addr->sa_data); - if (r) - return r; - } - - spin_lock_irqsave(&mac->lock, flags); - memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); - spin_unlock_irqrestore(&mac->lock, flags); - - return 0; -} - -static void set_multicast_hash_handler(struct work_struct *work) -{ - struct zd_mac *mac = container_of(work, struct zd_mac, - set_multicast_hash_work); - struct zd_mc_hash hash; - - spin_lock_irq(&mac->lock); - hash = mac->multicast_hash; - spin_unlock_irq(&mac->lock); - - zd_chip_set_multicast_hash(&mac->chip, &hash); -} - -void zd_mac_set_multicast_list(struct net_device *dev) -{ - struct zd_mac *mac = zd_netdev_mac(dev); - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - struct zd_mc_hash hash; - struct dev_mc_list *mc; - unsigned long flags; - DECLARE_MAC_BUF(mac2); - - if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) || - ieee->iw_mode == IW_MODE_MONITOR) { - zd_mc_add_all(&hash); - } else { - zd_mc_clear(&hash); - for (mc = dev->mc_list; mc; mc = mc->next) { - dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", - print_mac(mac2, mc->dmi_addr)); - zd_mc_add_addr(&hash, mc->dmi_addr); - } - } - - spin_lock_irqsave(&mac->lock, flags); - mac->multicast_hash = hash; - spin_unlock_irqrestore(&mac->lock, flags); - queue_work(zd_workqueue, &mac->set_multicast_hash_work); + while ((skb = skb_dequeue(ack_wait_queue))) + kfree_tx_skb(skb); } -int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain) -{ - int r; - u8 channel; - - ZD_ASSERT(!irqs_disabled()); - spin_lock_irq(&mac->lock); - if (regdomain == 0) { - regdomain = mac->default_regdomain; - } - if (!zd_regdomain_supported(regdomain)) { - spin_unlock_irq(&mac->lock); - return -EINVAL; - } - mac->regdomain = regdomain; - channel = mac->requested_channel; - spin_unlock_irq(&mac->lock); - - r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain); - if (r) - return r; - if (!zd_regdomain_supports_channel(regdomain, channel)) { - r = reset_channel(mac); - if (r) - return r; - } +/** + * init_tx_skb_control_block - initializes skb control block + * @skb: a &sk_buff pointer + * @dev: pointer to the mac80221 device + * @control: mac80211 tx control applying for the frame in @skb + * + * Initializes the control block of the skbuff to be transmitted. + */ +static int init_tx_skb_control_block(struct sk_buff *skb, + struct ieee80211_hw *hw, + struct ieee80211_tx_control *control) +{ + struct zd_tx_skb_control_block *cb = + (struct zd_tx_skb_control_block *)skb->cb; + + ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb)); + memset(cb, 0, sizeof(*cb)); + cb->hw= hw; + cb->control = kmalloc(sizeof(*control), GFP_ATOMIC); + if (cb->control == NULL) + return -ENOMEM; + memcpy(cb->control, control, sizeof(*control)); return 0; } -u8 zd_mac_get_regdomain(struct zd_mac *mac) -{ - unsigned long flags; - u8 regdomain; - - spin_lock_irqsave(&mac->lock, flags); - regdomain = mac->regdomain; - spin_unlock_irqrestore(&mac->lock, flags); - return regdomain; -} - -/* Fallback to lowest rate, if rate is unknown. */ -static u8 rate_to_zd_rate(u8 rate) -{ - switch (rate) { - case IEEE80211_CCK_RATE_2MB: - return ZD_CCK_RATE_2M; - case IEEE80211_CCK_RATE_5MB: - return ZD_CCK_RATE_5_5M; - case IEEE80211_CCK_RATE_11MB: - return ZD_CCK_RATE_11M; - case IEEE80211_OFDM_RATE_6MB: - return ZD_OFDM_RATE_6M; - case IEEE80211_OFDM_RATE_9MB: - return ZD_OFDM_RATE_9M; - case IEEE80211_OFDM_RATE_12MB: - return ZD_OFDM_RATE_12M; - case IEEE80211_OFDM_RATE_18MB: - return ZD_OFDM_RATE_18M; - case IEEE80211_OFDM_RATE_24MB: - return ZD_OFDM_RATE_24M; - case IEEE80211_OFDM_RATE_36MB: - return ZD_OFDM_RATE_36M; - case IEEE80211_OFDM_RATE_48MB: - return ZD_OFDM_RATE_48M; - case IEEE80211_OFDM_RATE_54MB: - return ZD_OFDM_RATE_54M; - } - return ZD_CCK_RATE_1M; -} - -static u16 rate_to_cr_rate(u8 rate) -{ - switch (rate) { - case IEEE80211_CCK_RATE_2MB: - return CR_RATE_1M; - case IEEE80211_CCK_RATE_5MB: - return CR_RATE_5_5M; - case IEEE80211_CCK_RATE_11MB: - return CR_RATE_11M; - case IEEE80211_OFDM_RATE_6MB: - return CR_RATE_6M; - case IEEE80211_OFDM_RATE_9MB: - return CR_RATE_9M; - case IEEE80211_OFDM_RATE_12MB: - return CR_RATE_12M; - case IEEE80211_OFDM_RATE_18MB: - return CR_RATE_18M; - case IEEE80211_OFDM_RATE_24MB: - return CR_RATE_24M; - case IEEE80211_OFDM_RATE_36MB: - return CR_RATE_36M; - case IEEE80211_OFDM_RATE_48MB: - return CR_RATE_48M; - case IEEE80211_OFDM_RATE_54MB: - return CR_RATE_54M; - } - return CR_RATE_1M; -} - -static void try_enable_tx(struct zd_mac *mac) -{ - unsigned long flags; - - spin_lock_irqsave(&mac->lock, flags); - if (mac->updating_rts_rate == 0 && mac->updating_basic_rates == 0) - netif_wake_queue(mac->netdev); - spin_unlock_irqrestore(&mac->lock, flags); -} - -static void set_rts_cts_work(struct work_struct *work) +/** + * tx_status - reports tx status of a packet if required + * @hw - a &struct ieee80211_hw pointer + * @skb - a sk-buffer + * @status - the tx status of the packet without control information + * @success - True for successfull transmission of the frame + * + * This information calls ieee80211_tx_status_irqsafe() if required by the + * control information. It copies the control information into the status + * information. + * + * If no status information has been requested, the skb is freed. + */ +static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ieee80211_tx_status *status, + bool success) { - struct zd_mac *mac = - container_of(work, struct zd_mac, set_rts_cts_work.work); - unsigned long flags; - u8 rts_rate; - unsigned int short_preamble; - - mutex_lock(&mac->chip.mutex); - - spin_lock_irqsave(&mac->lock, flags); - mac->updating_rts_rate = 0; - rts_rate = mac->rts_rate; - short_preamble = mac->short_preamble; - spin_unlock_irqrestore(&mac->lock, flags); - - zd_chip_set_rts_cts_rate_locked(&mac->chip, rts_rate, short_preamble); - mutex_unlock(&mac->chip.mutex); + struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *) + skb->cb; - try_enable_tx(mac); + ZD_ASSERT(cb->control != NULL); + memcpy(&status->control, cb->control, sizeof(status->control)); + if (!success) + status->excessive_retries = 1; + clear_tx_skb_control_block(skb); + ieee80211_tx_status_irqsafe(hw, skb, status); } -static void set_basic_rates_work(struct work_struct *work) +/** + * zd_mac_tx_failed - callback for failed frames + * @dev: the mac80211 wireless device + * + * This function is called if a frame couldn't be succesfully be + * transferred. The first frame from the tx queue, will be selected and + * reported as error to the upper layers. + */ +void zd_mac_tx_failed(struct ieee80211_hw *hw) { - struct zd_mac *mac = - container_of(work, struct zd_mac, set_basic_rates_work.work); - unsigned long flags; - u16 basic_rates; - - mutex_lock(&mac->chip.mutex); - - spin_lock_irqsave(&mac->lock, flags); - mac->updating_basic_rates = 0; - basic_rates = mac->basic_rates; - spin_unlock_irqrestore(&mac->lock, flags); - - zd_chip_set_basic_rates_locked(&mac->chip, basic_rates); - mutex_unlock(&mac->chip.mutex); + struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; + struct sk_buff *skb; + struct ieee80211_tx_status status = {{0}}; - try_enable_tx(mac); + skb = skb_dequeue(q); + if (skb == NULL) + return; + tx_status(hw, skb, &status, 0); } -static void bssinfo_change(struct net_device *netdev, u32 changes) -{ - struct zd_mac *mac = zd_netdev_mac(netdev); - struct ieee80211softmac_device *softmac = ieee80211_priv(netdev); - struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo; - int need_set_rts_cts = 0; - int need_set_rates = 0; - u16 basic_rates; - unsigned long flags; - - dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); - - if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) { - spin_lock_irqsave(&mac->lock, flags); - mac->short_preamble = bssinfo->short_preamble; - spin_unlock_irqrestore(&mac->lock, flags); - need_set_rts_cts = 1; - } - - if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) { - /* Set RTS rate to highest available basic rate */ - u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac, - &bssinfo->supported_rates, 1); - hi_rate = rate_to_zd_rate(hi_rate); - - spin_lock_irqsave(&mac->lock, flags); - if (hi_rate != mac->rts_rate) { - mac->rts_rate = hi_rate; - need_set_rts_cts = 1; - } - spin_unlock_irqrestore(&mac->lock, flags); - - /* Set basic rates */ - need_set_rates = 1; - if (bssinfo->supported_rates.count == 0) { - /* Allow the device to be flexible */ - basic_rates = CR_RATES_80211B | CR_RATES_80211G; +/** + * zd_mac_tx_to_dev - callback for USB layer + * @skb: a &sk_buff pointer + * @error: error value, 0 if transmission successful + * + * Informs the MAC layer that the frame has successfully transferred to the + * device. If an ACK is required and the transfer to the device has been + * successful, the packets are put on the @ack_wait_queue with + * the control set removed. + */ +void zd_mac_tx_to_dev(struct sk_buff *skb, int error) +{ + struct zd_tx_skb_control_block *cb = + (struct zd_tx_skb_control_block *)skb->cb; + struct ieee80211_hw *hw = cb->hw; + + if (likely(cb->control)) { + skb_pull(skb, sizeof(struct zd_ctrlset)); + if (unlikely(error || + (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) + { + struct ieee80211_tx_status status = {{0}}; + tx_status(hw, skb, &status, !error); } else { - int i = 0; - basic_rates = 0; + struct sk_buff_head *q = + &zd_hw_mac(hw)->ack_wait_queue; - for (i = 0; i < bssinfo->supported_rates.count; i++) { - u16 rate = bssinfo->supported_rates.rates[i]; - if ((rate & IEEE80211_BASIC_RATE_MASK) == 0) - continue; - - rate &= ~IEEE80211_BASIC_RATE_MASK; - basic_rates |= rate_to_cr_rate(rate); - } + skb_queue_tail(q, skb); + while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) + zd_mac_tx_failed(hw); } - spin_lock_irqsave(&mac->lock, flags); - mac->basic_rates = basic_rates; - spin_unlock_irqrestore(&mac->lock, flags); - } - - /* Schedule any changes we made above */ - - spin_lock_irqsave(&mac->lock, flags); - if (need_set_rts_cts && !mac->updating_rts_rate) { - mac->updating_rts_rate = 1; - netif_stop_queue(mac->netdev); - queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); - } - if (need_set_rates && !mac->updating_basic_rates) { - mac->updating_basic_rates = 1; - netif_stop_queue(mac->netdev); - queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, - 0); - } - spin_unlock_irqrestore(&mac->lock, flags); -} - -static void set_channel(struct net_device *netdev, u8 channel) -{ - struct zd_mac *mac = zd_netdev_mac(netdev); - - dev_dbg_f(zd_mac_dev(mac), "channel %d\n", channel); - - zd_chip_set_channel(&mac->chip, channel); -} - -int zd_mac_request_channel(struct zd_mac *mac, u8 channel) -{ - unsigned long lock_flags; - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - - if (ieee->iw_mode == IW_MODE_INFRA) - return -EPERM; - - spin_lock_irqsave(&mac->lock, lock_flags); - if (!zd_regdomain_supports_channel(mac->regdomain, channel)) { - spin_unlock_irqrestore(&mac->lock, lock_flags); - return -EINVAL; - } - mac->requested_channel = channel; - spin_unlock_irqrestore(&mac->lock, lock_flags); - if (netif_running(mac->netdev)) - return zd_chip_set_channel(&mac->chip, channel); - else - return 0; -} - -u8 zd_mac_get_channel(struct zd_mac *mac) -{ - u8 channel = zd_chip_get_channel(&mac->chip); - - dev_dbg_f(zd_mac_dev(mac), "channel %u\n", channel); - return channel; -} - -int zd_mac_set_mode(struct zd_mac *mac, u32 mode) -{ - struct ieee80211_device *ieee; - - switch (mode) { - case IW_MODE_AUTO: - case IW_MODE_ADHOC: - case IW_MODE_INFRA: - mac->netdev->type = ARPHRD_ETHER; - break; - case IW_MODE_MONITOR: - mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP; - break; - default: - dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode); - return -EINVAL; - } - - ieee = zd_mac_to_ieee80211(mac); - ZD_ASSERT(!irqs_disabled()); - spin_lock_irq(&ieee->lock); - ieee->iw_mode = mode; - spin_unlock_irq(&ieee->lock); - - if (netif_running(mac->netdev)) { - int r = set_rx_filter(mac); - if (r) - return r; - return set_sniffer(mac); - } - - return 0; -} - -int zd_mac_get_mode(struct zd_mac *mac, u32 *mode) -{ - unsigned long flags; - struct ieee80211_device *ieee; - - ieee = zd_mac_to_ieee80211(mac); - spin_lock_irqsave(&ieee->lock, flags); - *mode = ieee->iw_mode; - spin_unlock_irqrestore(&ieee->lock, flags); - return 0; -} - -int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range) -{ - int i; - const struct channel_range *channel_range; - u8 regdomain; - - memset(range, 0, sizeof(*range)); - - /* FIXME: Not so important and depends on the mode. For 802.11g - * usually this value is used. It seems to be that Bit/s number is - * given here. - */ - range->throughput = 27 * 1000 * 1000; - - range->max_qual.qual = 100; - range->max_qual.level = 100; - - /* FIXME: Needs still to be tuned. */ - range->avg_qual.qual = 71; - range->avg_qual.level = 80; - - /* FIXME: depends on standard? */ - range->min_rts = 256; - range->max_rts = 2346; - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->max_encoding_tokens = WEP_KEYS; - range->num_encoding_sizes = 2; - range->encoding_size[0] = 5; - range->encoding_size[1] = WEP_KEY_LEN; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 20; - - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - ZD_ASSERT(!irqs_disabled()); - spin_lock_irq(&mac->lock); - regdomain = mac->regdomain; - spin_unlock_irq(&mac->lock); - channel_range = zd_channel_range(regdomain); - - range->num_channels = channel_range->end - channel_range->start; - range->old_num_channels = range->num_channels; - range->num_frequency = range->num_channels; - range->old_num_frequency = range->num_frequency; - - for (i = 0; i < range->num_frequency; i++) { - struct iw_freq *freq = &range->freq[i]; - freq->i = channel_range->start + i; - zd_channel_to_freq(freq, freq->i); + } else { + kfree_tx_skb(skb); } - - return 0; } static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) { /* ZD_PURE_RATE() must be used to remove the modulation type flag of - * the zd-rate values. */ + * the zd-rate values. + */ static const u8 rate_divisor[] = { - [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, - [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, - - /* bits must be doubled */ - [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, - - [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, - [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, - [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, - [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, - [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, - [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, - [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, - [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, - [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, + [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, + [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, + /* Bits must be doubled. */ + [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, + [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, + [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, + [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, + [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, + [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, + [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, + [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, + [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, + [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, }; u32 bits = (u32)tx_length * 8; @@ -764,34 +451,10 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) return bits/divisor; } -static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, - struct ieee80211_hdr_4addr *hdr) -{ - struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); - u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); - u8 rate; - int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; - int is_multicast = is_multicast_ether_addr(hdr->addr1); - int short_preamble = ieee80211softmac_short_preamble_ok(softmac, - is_multicast, is_mgt); - - rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt); - cs->modulation = rate_to_zd_rate(rate); - - /* Set short preamble bit when appropriate */ - if (short_preamble && ZD_MODULATION_TYPE(cs->modulation) == ZD_CCK - && cs->modulation != ZD_CCK_RATE_1M) - cs->modulation |= ZD_CCK_PREA_SHORT; -} - static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, - struct ieee80211_hdr_4addr *header) + struct ieee80211_hdr *header, u32 flags) { - struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); - unsigned int tx_length = le16_to_cpu(cs->tx_length); - u16 fctl = le16_to_cpu(header->frame_ctl); - u16 ftype = WLAN_FC_GET_TYPE(fctl); - u16 stype = WLAN_FC_GET_STYPE(fctl); + u16 fctl = le16_to_cpu(header->frame_control); /* * CONTROL TODO: @@ -802,7 +465,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, cs->control = 0; /* First fragment */ - if (WLAN_GET_SEQ_FRAG(le16_to_cpu(header->seq_ctl)) == 0) + if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT) cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; /* Multicast */ @@ -810,54 +473,37 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, cs->control |= ZD_CS_MULTICAST; /* PS-POLL */ - if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) + if ((fctl & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) == + (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) cs->control |= ZD_CS_PS_POLL_FRAME; - /* Unicast data frames over the threshold should have RTS */ - if (!is_multicast_ether_addr(header->addr1) && - ftype != IEEE80211_FTYPE_MGMT && - tx_length > zd_netdev_ieee80211(mac->netdev)->rts) + if (flags & IEEE80211_TXCTL_USE_RTS_CTS) cs->control |= ZD_CS_RTS; - /* Use CTS-to-self protection if required */ - if (ZD_MODULATION_TYPE(cs->modulation) == ZD_OFDM && - ieee80211softmac_protection_needed(softmac)) { - /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */ - cs->control &= ~ZD_CS_RTS; + if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT) cs->control |= ZD_CS_SELF_CTS; - } /* FIXME: Management frame? */ } static int fill_ctrlset(struct zd_mac *mac, - struct ieee80211_txb *txb, - int frag_num) + struct sk_buff *skb, + struct ieee80211_tx_control *control) { int r; - struct sk_buff *skb = txb->fragments[frag_num]; - struct ieee80211_hdr_4addr *hdr = - (struct ieee80211_hdr_4addr *) skb->data; - unsigned int frag_len = skb->len + IEEE80211_FCS_LEN; - unsigned int next_frag_len; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + unsigned int frag_len = skb->len + FCS_LEN; unsigned int packet_length; struct zd_ctrlset *cs = (struct zd_ctrlset *) skb_push(skb, sizeof(struct zd_ctrlset)); - if (frag_num+1 < txb->nr_frags) { - next_frag_len = txb->fragments[frag_num+1]->len + - IEEE80211_FCS_LEN; - } else { - next_frag_len = 0; - } ZD_ASSERT(frag_len <= 0xffff); - ZD_ASSERT(next_frag_len <= 0xffff); - cs_set_modulation(mac, cs, hdr); + cs->modulation = control->tx_rate; cs->tx_length = cpu_to_le16(frag_len); - cs_set_control(mac, cs, hdr); + cs_set_control(mac, cs, hdr, control->flags); packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; ZD_ASSERT(packet_length <= 0xffff); @@ -886,413 +532,399 @@ static int fill_ctrlset(struct zd_mac *mac, if (r < 0) return r; cs->current_length = cpu_to_le16(r); - - if (next_frag_len == 0) { - cs->next_frame_length = 0; - } else { - r = zd_calc_tx_length_us(NULL, ZD_RATE(cs->modulation), - next_frag_len); - if (r < 0) - return r; - cs->next_frame_length = cpu_to_le16(r); - } + cs->next_frame_length = 0; return 0; } -static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) +/** + * zd_op_tx - transmits a network frame to the device + * + * @dev: mac80211 hardware device + * @skb: socket buffer + * @control: the control structure + * + * This function transmit an IEEE 802.11 network frame to the device. The + * control block of the skbuff will be initialized. If necessary the incoming + * mac80211 queues will be stopped. + */ +static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ieee80211_tx_control *control) { - int i, r; - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + struct zd_mac *mac = zd_hw_mac(hw); + int r; - for (i = 0; i < txb->nr_frags; i++) { - struct sk_buff *skb = txb->fragments[i]; + r = fill_ctrlset(mac, skb, control); + if (r) + return r; - r = fill_ctrlset(mac, txb, i); - if (r) { - ieee->stats.tx_dropped++; - return r; - } - r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len); - if (r) { - ieee->stats.tx_dropped++; - return r; - } + r = init_tx_skb_control_block(skb, hw, control); + if (r) + return r; + r = zd_usb_tx(&mac->chip.usb, skb); + if (r) { + clear_tx_skb_control_block(skb); + return r; } - - /* FIXME: shouldn't this be handled by the upper layers? */ - mac->netdev->trans_start = jiffies; - - ieee80211_txb_free(txb); return 0; } -struct zd_rt_hdr { - struct ieee80211_radiotap_header rt_hdr; - u8 rt_flags; - u8 rt_rate; - u16 rt_channel; - u16 rt_chbitmask; -} __attribute__((packed)); - -static void fill_rt_header(void *buffer, struct zd_mac *mac, - const struct ieee80211_rx_stats *stats, - const struct rx_status *status) -{ - struct zd_rt_hdr *hdr = buffer; - - hdr->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; - hdr->rt_hdr.it_pad = 0; - hdr->rt_hdr.it_len = cpu_to_le16(sizeof(struct zd_rt_hdr)); - hdr->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_CHANNEL) | - (1 << IEEE80211_RADIOTAP_RATE)); - - hdr->rt_flags = 0; - if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) - hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; - - hdr->rt_rate = stats->rate / 5; - - /* FIXME: 802.11a */ - hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( - _zd_chip_get_channel(&mac->chip))); - hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | - ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == - ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); -} - -/* Returns 1 if the data packet is for us and 0 otherwise. */ -static int is_data_packet_for_us(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *hdr) -{ - struct net_device *netdev = ieee->dev; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA); - - switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 || - compare_ether_addr(hdr->addr3, ieee->bssid) != 0) - return 0; - break; - case IW_MODE_AUTO: - case IW_MODE_INFRA: - if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != - IEEE80211_FCTL_FROMDS || - compare_ether_addr(hdr->addr2, ieee->bssid) != 0) - return 0; - break; - default: - ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR); - return 0; - } - - return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 || - (is_multicast_ether_addr(hdr->addr1) && - compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) || - (netdev->flags & IFF_PROMISC); -} - -/* Filters received packets. The function returns 1 if the packet should be - * forwarded to ieee80211_rx(). If the packet should be ignored the function - * returns 0. If an invalid packet is found the function returns -EINVAL. +/** + * filter_ack - filters incoming packets for acknowledgements + * @dev: the mac80211 device + * @rx_hdr: received header + * @stats: the status for the received packet * - * The function calls ieee80211_rx_mgt() directly. + * This functions looks for ACK packets and tries to match them with the + * frames in the tx queue. If a match is found the frame will be dequeued and + * the upper layers is informed about the successful transmission. If + * mac80211 queues have been stopped and the number of frames still to be + * transmitted is low the queues will be opened again. * - * It has been based on ieee80211_rx_any. + * Returns 1 if the frame was an ACK, 0 if it was ignored. */ -static int filter_rx(struct ieee80211_device *ieee, - const u8 *buffer, unsigned int length, - struct ieee80211_rx_stats *stats) +static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, + struct ieee80211_rx_status *stats) { - struct ieee80211_hdr_4addr *hdr; - u16 fc; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return 1; - - hdr = (struct ieee80211_hdr_4addr *)buffer; - fc = le16_to_cpu(hdr->frame_ctl); - if ((fc & IEEE80211_FCTL_VERS) != 0) - return -EINVAL; + u16 fc = le16_to_cpu(rx_hdr->frame_control); + struct sk_buff *skb; + struct sk_buff_head *q; + unsigned long flags; - switch (WLAN_FC_GET_TYPE(fc)) { - case IEEE80211_FTYPE_MGMT: - if (length < sizeof(struct ieee80211_hdr_3addr)) - return -EINVAL; - ieee80211_rx_mgt(ieee, hdr, stats); + if ((fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) != + (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK)) return 0; - case IEEE80211_FTYPE_CTL: - return 0; - case IEEE80211_FTYPE_DATA: - /* Ignore invalid short buffers */ - if (length < sizeof(struct ieee80211_hdr_3addr)) - return -EINVAL; - return is_data_packet_for_us(ieee, hdr); - } - return -EINVAL; + q = &zd_hw_mac(hw)->ack_wait_queue; + spin_lock_irqsave(&q->lock, flags); + for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) { + struct ieee80211_hdr *tx_hdr; + + tx_hdr = (struct ieee80211_hdr *)skb->data; + if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) + { + struct ieee80211_tx_status status = {{0}}; + status.flags = IEEE80211_TX_STATUS_ACK; + status.ack_signal = stats->ssi; + __skb_unlink(skb, q); + tx_status(hw, skb, &status, 1); + goto out; + } + } +out: + spin_unlock_irqrestore(&q->lock, flags); + return 1; } -static void update_qual_rssi(struct zd_mac *mac, - const u8 *buffer, unsigned int length, - u8 qual_percent, u8 rssi_percent) +int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) { - unsigned long flags; - struct ieee80211_hdr_3addr *hdr; - int i; + struct zd_mac *mac = zd_hw_mac(hw); + struct ieee80211_rx_status stats; + const struct rx_status *status; + struct sk_buff *skb; + int bad_frame = 0; - hdr = (struct ieee80211_hdr_3addr *)buffer; - if (length < offsetof(struct ieee80211_hdr_3addr, addr3)) - return; - if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0) - return; + if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + + FCS_LEN + sizeof(struct rx_status)) + return -EINVAL; - spin_lock_irqsave(&mac->lock, flags); - i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE; - mac->qual_buffer[i] = qual_percent; - mac->rssi_buffer[i] = rssi_percent; - mac->stats_count++; - spin_unlock_irqrestore(&mac->lock, flags); -} + memset(&stats, 0, sizeof(stats)); -static int fill_rx_stats(struct ieee80211_rx_stats *stats, - const struct rx_status **pstatus, - struct zd_mac *mac, - const u8 *buffer, unsigned int length) -{ - const struct rx_status *status; + /* Note about pass_failed_fcs and pass_ctrl access below: + * mac locking intentionally omitted here, as this is the only unlocked + * reader and the only writer is configure_filter. Plus, if there were + * any races accessing these variables, it wouldn't really matter. + * If mac80211 ever provides a way for us to access filter flags + * from outside configure_filter, we could improve on this. Also, this + * situation may change once we implement some kind of DMA-into-skb + * RX path. */ - *pstatus = status = (struct rx_status *) + /* Caller has to ensure that length >= sizeof(struct rx_status). */ + status = (struct rx_status *) (buffer + (length - sizeof(struct rx_status))); if (status->frame_status & ZD_RX_ERROR) { - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - ieee->stats.rx_errors++; - if (status->frame_status & ZD_RX_TIMEOUT_ERROR) - ieee->stats.rx_missed_errors++; - else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) - ieee->stats.rx_fifo_errors++; - else if (status->frame_status & ZD_RX_DECRYPTION_ERROR) - ieee->ieee_stats.rx_discards_undecryptable++; - else if (status->frame_status & ZD_RX_CRC32_ERROR) { - ieee->stats.rx_crc_errors++; - ieee->ieee_stats.rx_fcs_errors++; + if (mac->pass_failed_fcs && + (status->frame_status & ZD_RX_CRC32_ERROR)) { + stats.flag |= RX_FLAG_FAILED_FCS_CRC; + bad_frame = 1; + } else { + return -EINVAL; } - else if (status->frame_status & ZD_RX_CRC16_ERROR) - ieee->stats.rx_crc_errors++; - return -EINVAL; } - memset(stats, 0, sizeof(struct ieee80211_rx_stats)); - stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN + - + sizeof(struct rx_status)); - /* FIXME: 802.11a */ - stats->freq = IEEE80211_24GHZ_BAND; - stats->received_channel = _zd_chip_get_channel(&mac->chip); - stats->rssi = zd_rx_strength_percent(status->signal_strength); - stats->signal = zd_rx_qual_percent(buffer, + stats.channel = _zd_chip_get_channel(&mac->chip); + stats.freq = zd_channels[stats.channel - 1].freq; + stats.phymode = MODE_IEEE80211G; + stats.ssi = status->signal_strength; + stats.signal = zd_rx_qual_percent(buffer, length - sizeof(struct rx_status), status); - stats->mask = IEEE80211_STATMASK_RSSI | IEEE80211_STATMASK_SIGNAL; - stats->rate = zd_rx_rate(buffer, status); - if (stats->rate) - stats->mask |= IEEE80211_STATMASK_RATE; + stats.rate = zd_rx_rate(buffer, status); + + length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); + buffer += ZD_PLCP_HEADER_SIZE; + + /* Except for bad frames, filter each frame to see if it is an ACK, in + * which case our internal TX tracking is updated. Normally we then + * bail here as there's no need to pass ACKs on up to the stack, but + * there is also the case where the stack has requested us to pass + * control frames on up (pass_ctrl) which we must consider. */ + if (!bad_frame && + filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) + && !mac->pass_ctrl) + return 0; + skb = dev_alloc_skb(length); + if (skb == NULL) + return -ENOMEM; + memcpy(skb_put(skb, length), buffer, length); + + ieee80211_rx_irqsafe(hw, skb, &stats); return 0; } -static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) +static int zd_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) { - int r; - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - struct ieee80211_rx_stats stats; - const struct rx_status *status; + struct zd_mac *mac = zd_hw_mac(hw); - if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + - IEEE80211_FCS_LEN + sizeof(struct rx_status)) - { - ieee->stats.rx_errors++; - ieee->stats.rx_length_errors++; - goto free_skb; - } + /* using IEEE80211_IF_TYPE_INVALID to indicate no mode selected */ + if (mac->type != IEEE80211_IF_TYPE_INVALID) + return -EOPNOTSUPP; - r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); - if (r) { - /* Only packets with rx errors are included here. - * The error stats have already been set in fill_rx_stats. - */ - goto free_skb; + switch (conf->type) { + case IEEE80211_IF_TYPE_MNTR: + case IEEE80211_IF_TYPE_STA: + mac->type = conf->type; + break; + default: + return -EOPNOTSUPP; } - __skb_pull(skb, ZD_PLCP_HEADER_SIZE); - __skb_trim(skb, skb->len - - (IEEE80211_FCS_LEN + sizeof(struct rx_status))); - - update_qual_rssi(mac, skb->data, skb->len, stats.signal, - status->signal_strength); - - r = filter_rx(ieee, skb->data, skb->len, &stats); - if (r <= 0) { - if (r < 0) { - ieee->stats.rx_errors++; - dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); - } - goto free_skb; - } + return zd_write_mac_addr(&mac->chip, conf->mac_addr); +} - if (ieee->iw_mode == IW_MODE_MONITOR) - fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, - &stats, status); +static void zd_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_if_init_conf *conf) +{ + struct zd_mac *mac = zd_hw_mac(hw); + mac->type = IEEE80211_IF_TYPE_INVALID; + zd_write_mac_addr(&mac->chip, NULL); +} - r = ieee80211_rx(ieee, skb, &stats); - if (r) - return; -free_skb: - /* We are always in a soft irq. */ - dev_kfree_skb(skb); +static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) +{ + struct zd_mac *mac = zd_hw_mac(hw); + return zd_chip_set_channel(&mac->chip, conf->channel); } -static void do_rx(unsigned long mac_ptr) +static int zd_op_config_interface(struct ieee80211_hw *hw, int if_id, + struct ieee80211_if_conf *conf) { - struct zd_mac *mac = (struct zd_mac *)mac_ptr; - struct sk_buff *skb; + struct zd_mac *mac = zd_hw_mac(hw); - while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) - zd_mac_rx(mac, skb); + spin_lock_irq(&mac->lock); + mac->associated = is_valid_ether_addr(conf->bssid); + spin_unlock_irq(&mac->lock); + + /* TODO: do hardware bssid filtering */ + return 0; } -int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) +static void set_multicast_hash_handler(struct work_struct *work) { - struct sk_buff *skb; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_multicast_hash_work); + struct zd_mc_hash hash; - skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); - if (!skb) { - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); - ieee->stats.rx_dropped++; - return -ENOMEM; - } - skb_reserve(skb, sizeof(struct zd_rt_hdr)); - memcpy(__skb_put(skb, length), buffer, length); - skb_queue_tail(&mac->rx_queue, skb); - tasklet_schedule(&mac->rx_tasklet); - return 0; + spin_lock_irq(&mac->lock); + hash = mac->multicast_hash; + spin_unlock_irq(&mac->lock); + + zd_chip_set_multicast_hash(&mac->chip, &hash); } -static int netdev_tx(struct ieee80211_txb *txb, struct net_device *netdev, - int pri) +static void set_rx_filter_handler(struct work_struct *work) { - return zd_mac_tx(zd_netdev_mac(netdev), txb, pri); + struct zd_mac *mac = + container_of(work, struct zd_mac, set_rx_filter_work); + int r; + + dev_dbg_f(zd_mac_dev(mac), "\n"); + r = set_rx_filter(mac); + if (r) + dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); } -static void set_security(struct net_device *netdev, - struct ieee80211_security *sec) +#define SUPPORTED_FIF_FLAGS \ + (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ + FIF_OTHER_BSS) +static void zd_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + int mc_count, struct dev_mc_list *mclist) { - struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev); - struct ieee80211_security *secinfo = &ieee->sec; - int keyidx; - - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n"); - - for (keyidx = 0; keyidxflags & (1<encode_alg[keyidx] = sec->encode_alg[keyidx]; - secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx]; - memcpy(secinfo->keys[keyidx], sec->keys[keyidx], - SCM_KEY_LEN); - } + struct zd_mc_hash hash; + struct zd_mac *mac = zd_hw_mac(hw); + unsigned long flags; + int i; - if (sec->flags & SEC_ACTIVE_KEY) { - secinfo->active_key = sec->active_key; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .active_key = %d\n", sec->active_key); - } - if (sec->flags & SEC_UNICAST_GROUP) { - secinfo->unicast_uses_group = sec->unicast_uses_group; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .unicast_uses_group = %d\n", - sec->unicast_uses_group); - } - if (sec->flags & SEC_LEVEL) { - secinfo->level = sec->level; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .level = %d\n", sec->level); - } - if (sec->flags & SEC_ENABLED) { - secinfo->enabled = sec->enabled; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .enabled = %d\n", sec->enabled); - } - if (sec->flags & SEC_ENCRYPT) { - secinfo->encrypt = sec->encrypt; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .encrypt = %d\n", sec->encrypt); - } - if (sec->flags & SEC_AUTH_MODE) { - secinfo->auth_mode = sec->auth_mode; - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), - " .auth_mode = %d\n", sec->auth_mode); + /* Only deal with supported flags */ + changed_flags &= SUPPORTED_FIF_FLAGS; + *new_flags &= SUPPORTED_FIF_FLAGS; + + /* changed_flags is always populated but this driver + * doesn't support all FIF flags so its possible we don't + * need to do anything */ + if (!changed_flags) + return; + + if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) { + zd_mc_add_all(&hash); + } else { + DECLARE_MAC_BUF(macbuf); + + zd_mc_clear(&hash); + for (i = 0; i < mc_count; i++) { + if (!mclist) + break; + dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", + print_mac(macbuf, mclist->dmi_addr)); + zd_mc_add_addr(&hash, mclist->dmi_addr); + mclist = mclist->next; + } } + + spin_lock_irqsave(&mac->lock, flags); + mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL); + mac->pass_ctrl = !!(*new_flags & FIF_CONTROL); + mac->multicast_hash = hash; + spin_unlock_irqrestore(&mac->lock, flags); + queue_work(zd_workqueue, &mac->set_multicast_hash_work); + + if (changed_flags & FIF_CONTROL) + queue_work(zd_workqueue, &mac->set_rx_filter_work); + + /* no handling required for FIF_OTHER_BSS as we don't currently + * do BSSID filtering */ + /* FIXME: in future it would be nice to enable the probe response + * filter (so that the driver doesn't see them) until + * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd + * have to schedule work to enable prbresp reception, which might + * happen too late. For now we'll just listen and forward them all the + * time. */ } -static void ieee_init(struct ieee80211_device *ieee) +static void set_rts_cts_work(struct work_struct *work) { - ieee->mode = IEEE_B | IEEE_G; - ieee->freq_band = IEEE80211_24GHZ_BAND; - ieee->modulation = IEEE80211_OFDM_MODULATION | IEEE80211_CCK_MODULATION; - ieee->tx_headroom = sizeof(struct zd_ctrlset); - ieee->set_security = set_security; - ieee->hard_start_xmit = netdev_tx; - - /* Software encryption/decryption for now */ - ieee->host_build_iv = 0; - ieee->host_encrypt = 1; - ieee->host_decrypt = 1; - - /* FIXME: default to managed mode, until ieee80211 and zd1211rw can - * correctly support AUTO */ - ieee->iw_mode = IW_MODE_INFRA; + struct zd_mac *mac = + container_of(work, struct zd_mac, set_rts_cts_work); + unsigned long flags; + unsigned int short_preamble; + + mutex_lock(&mac->chip.mutex); + + spin_lock_irqsave(&mac->lock, flags); + mac->updating_rts_rate = 0; + short_preamble = mac->short_preamble; + spin_unlock_irqrestore(&mac->lock, flags); + + zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble); + mutex_unlock(&mac->chip.mutex); } -static void softmac_init(struct ieee80211softmac_device *sm) +static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, + int cts_protection, int preamble) { - sm->set_channel = set_channel; - sm->bssinfo_change = bssinfo_change; + struct zd_mac *mac = zd_hw_mac(hw); + unsigned long flags; + + dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); + + if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) { + spin_lock_irqsave(&mac->lock, flags); + mac->short_preamble = !preamble; + if (!mac->updating_rts_rate) { + mac->updating_rts_rate = 1; + /* FIXME: should disable TX here, until work has + * completed and RTS_CTS reg is updated */ + queue_work(zd_workqueue, &mac->set_rts_cts_work); + } + spin_unlock_irqrestore(&mac->lock, flags); + } } -struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) +static const struct ieee80211_ops zd_ops = { + .tx = zd_op_tx, + .start = zd_op_start, + .stop = zd_op_stop, + .add_interface = zd_op_add_interface, + .remove_interface = zd_op_remove_interface, + .config = zd_op_config, + .config_interface = zd_op_config_interface, + .configure_filter = zd_op_configure_filter, + .erp_ie_changed = zd_op_erp_ie_changed, +}; + +struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) { - struct zd_mac *mac = zd_netdev_mac(ndev); - struct iw_statistics *iw_stats = &mac->iw_stats; - unsigned int i, count, qual_total, rssi_total; + struct zd_mac *mac; + struct ieee80211_hw *hw; + int i; - memset(iw_stats, 0, sizeof(struct iw_statistics)); - /* We are not setting the status, because ieee->state is not updated - * at all and this driver doesn't track authentication state. - */ - spin_lock_irq(&mac->lock); - count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ? - mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE; - qual_total = rssi_total = 0; - for (i = 0; i < count; i++) { - qual_total += mac->qual_buffer[i]; - rssi_total += mac->rssi_buffer[i]; + hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); + if (!hw) { + dev_dbg_f(&intf->dev, "out of memory\n"); + return NULL; } - spin_unlock_irq(&mac->lock); - iw_stats->qual.updated = IW_QUAL_NOISE_INVALID; - if (count > 0) { - iw_stats->qual.qual = qual_total / count; - iw_stats->qual.level = rssi_total / count; - iw_stats->qual.updated |= - IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED; - } else { - iw_stats->qual.updated |= - IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID; + + mac = zd_hw_mac(hw); + + memset(mac, 0, sizeof(*mac)); + spin_lock_init(&mac->lock); + mac->hw = hw; + + mac->type = IEEE80211_IF_TYPE_INVALID; + + memcpy(mac->channels, zd_channels, sizeof(zd_channels)); + memcpy(mac->rates, zd_rates, sizeof(zd_rates)); + mac->modes[0].mode = MODE_IEEE80211G; + mac->modes[0].num_rates = ARRAY_SIZE(zd_rates); + mac->modes[0].rates = mac->rates; + mac->modes[0].num_channels = ARRAY_SIZE(zd_channels); + mac->modes[0].channels = mac->channels; + mac->modes[1].mode = MODE_IEEE80211B; + mac->modes[1].num_rates = 4; + mac->modes[1].rates = mac->rates; + mac->modes[1].num_channels = ARRAY_SIZE(zd_channels); + mac->modes[1].channels = mac->channels; + + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; + hw->max_rssi = 100; + hw->max_signal = 100; + + hw->queues = 1; + hw->extra_tx_headroom = sizeof(struct zd_ctrlset); + + skb_queue_head_init(&mac->ack_wait_queue); + + for (i = 0; i < 2; i++) { + if (ieee80211_register_hwmode(hw, &mac->modes[i])) { + dev_dbg_f(&intf->dev, "cannot register hwmode\n"); + ieee80211_free_hw(hw); + return NULL; + } } - /* TODO: update counter */ - return iw_stats; + + zd_chip_init(&mac->chip, hw, intf); + housekeeping_init(mac); + INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); + INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); + INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); + + SET_IEEE80211_DEV(hw, &intf->dev); + return hw; } #define LINK_LED_WORK_DELAY HZ @@ -1302,18 +934,17 @@ static void link_led_handler(struct work_struct *work) struct zd_mac *mac = container_of(work, struct zd_mac, housekeeping.link_led_work.work); struct zd_chip *chip = &mac->chip; - struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); int is_associated; int r; spin_lock_irq(&mac->lock); - is_associated = sm->associnfo.associated != 0; + is_associated = mac->associated; spin_unlock_irq(&mac->lock); r = zd_chip_control_leds(chip, is_associated ? LED_ASSOCIATED : LED_SCANNING); if (r) - dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); + dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, LINK_LED_WORK_DELAY); diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 1b15bde..2dde108 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h @@ -1,4 +1,7 @@ -/* zd_mac.h +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -18,14 +21,11 @@ #ifndef _ZD_MAC_H #define _ZD_MAC_H -#include #include -#include -#include -#include +#include #include "zd_chip.h" -#include "zd_netdev.h" +#include "zd_ieee80211.h" struct zd_ctrlset { u8 modulation; @@ -57,7 +57,7 @@ struct zd_ctrlset { /* The two possible modulation types. Notify that 802.11b doesn't use the CCK * codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain * consistent with uses the term at other places. - */ + */ #define ZD_CCK 0x00 #define ZD_OFDM 0x10 @@ -141,58 +141,68 @@ struct rx_status { #define ZD_RX_CRC16_ERROR 0x40 #define ZD_RX_ERROR 0x80 +enum mac_flags { + MAC_FIXED_CHANNEL = 0x01, +}; + struct housekeeping { struct delayed_work link_led_work; }; +/** + * struct zd_tx_skb_control_block - control block for tx skbuffs + * @control: &struct ieee80211_tx_control pointer + * @context: context pointer + * + * This structure is used to fill the cb field in an &sk_buff to transmit. + * The control field is NULL, if there is no requirement from the mac80211 + * stack to report about the packet ACK. This is the case if the flag + * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control. + */ +struct zd_tx_skb_control_block { + struct ieee80211_tx_control *control; + struct ieee80211_hw *hw; + void *context; +}; + #define ZD_MAC_STATS_BUFFER_SIZE 16 +#define ZD_MAC_MAX_ACK_WAITERS 10 + struct zd_mac { struct zd_chip chip; spinlock_t lock; - struct net_device *netdev; - - /* Unlocked reading possible */ - struct iw_statistics iw_stats; - + struct ieee80211_hw *hw; struct housekeeping housekeeping; struct work_struct set_multicast_hash_work; + struct work_struct set_rts_cts_work; + struct work_struct set_rx_filter_work; struct zd_mc_hash multicast_hash; - struct delayed_work set_rts_cts_work; - struct delayed_work set_basic_rates_work; - - struct tasklet_struct rx_tasklet; - struct sk_buff_head rx_queue; - - unsigned int stats_count; - u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; - u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; u8 regdomain; u8 default_regdomain; - u8 requested_channel; - - /* A bitpattern of cr_rates */ - u16 basic_rates; - - /* A zd_rate */ - u8 rts_rate; + int type; + int associated; + struct sk_buff_head ack_wait_queue; + struct ieee80211_channel channels[14]; + struct ieee80211_rate rates[12]; + struct ieee80211_hw_mode modes[2]; /* Short preamble (used for RTS/CTS) */ unsigned int short_preamble:1; /* flags to indicate update in progress */ unsigned int updating_rts_rate:1; - unsigned int updating_basic_rates:1; -}; -static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) -{ - return zd_netdev_ieee80211(mac->netdev); -} + /* whether to pass frames with CRC errors to stack */ + unsigned int pass_failed_fcs:1; -static inline struct zd_mac *zd_netdev_mac(struct net_device *netdev) + /* whether to pass control frames to stack */ + unsigned int pass_ctrl:1; +}; + +static inline struct zd_mac *zd_hw_mac(struct ieee80211_hw *hw) { - return ieee80211softmac_priv(netdev); + return hw->priv; } static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip) @@ -205,35 +215,22 @@ static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb) return zd_chip_to_mac(zd_usb_to_chip(usb)); } +static inline u8 *zd_mac_get_perm_addr(struct zd_mac *mac) +{ + return mac->hw->wiphy->perm_addr; +} + #define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip)) -int zd_mac_init(struct zd_mac *mac, - struct net_device *netdev, - struct usb_interface *intf); +struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf); void zd_mac_clear(struct zd_mac *mac); -int zd_mac_preinit_hw(struct zd_mac *mac); -int zd_mac_init_hw(struct zd_mac *mac); - -int zd_mac_open(struct net_device *netdev); -int zd_mac_stop(struct net_device *netdev); -int zd_mac_set_mac_address(struct net_device *dev, void *p); -void zd_mac_set_multicast_list(struct net_device *netdev); - -int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); - -int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); -u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); - -int zd_mac_request_channel(struct zd_mac *mac, u8 channel); -u8 zd_mac_get_channel(struct zd_mac *mac); - -int zd_mac_set_mode(struct zd_mac *mac, u32 mode); -int zd_mac_get_mode(struct zd_mac *mac, u32 *mode); - -int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range); +int zd_mac_preinit_hw(struct ieee80211_hw *hw); +int zd_mac_init_hw(struct ieee80211_hw *hw); -struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev); +int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); +void zd_mac_tx_failed(struct ieee80211_hw *hw); +void zd_mac_tx_to_dev(struct sk_buff *skb, int error); #ifdef DEBUG void zd_dump_rx_status(const struct rx_status *status); diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c deleted file mode 100644 index 047cab3..0000000 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ /dev/null @@ -1,264 +0,0 @@ -/* zd_netdev.c - * - * 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 "zd_def.h" -#include "zd_netdev.h" -#include "zd_mac.h" -#include "zd_ieee80211.h" - -/* Region 0 means reset regdomain to default. */ -static int zd_set_regdomain(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - const u8 *regdomain = (u8 *)req; - return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain); -} - -static int zd_get_regdomain(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - u8 *regdomain = (u8 *)req; - if (!regdomain) - return -EINVAL; - *regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev)); - return 0; -} - -static const struct iw_priv_args zd_priv_args[] = { - { - .cmd = ZD_PRIV_SET_REGDOMAIN, - .set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - .name = "set_regdomain", - }, - { - .cmd = ZD_PRIV_GET_REGDOMAIN, - .get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, - .name = "get_regdomain", - }, -}; - -#define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV] - -static const iw_handler zd_priv_handler[] = { - PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain, - PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain, -}; - -static int iw_get_name(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - /* FIXME: check whether 802.11a will also supported */ - strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ); - return 0; -} - -static int iw_get_nick(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - strcpy(extra, "zd1211"); - req->data.length = strlen(extra); - req->data.flags = 1; - return 0; -} - -static int iw_set_freq(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - int r; - struct zd_mac *mac = zd_netdev_mac(netdev); - struct iw_freq *freq = &req->freq; - u8 channel; - - r = zd_find_channel(&channel, freq); - if (r < 0) - return r; - r = zd_mac_request_channel(mac, channel); - return r; -} - -static int iw_get_freq(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - struct zd_mac *mac = zd_netdev_mac(netdev); - struct iw_freq *freq = &req->freq; - - return zd_channel_to_freq(freq, zd_mac_get_channel(mac)); -} - -static int iw_set_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode); -} - -static int iw_get_mode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode); -} - -static int iw_get_range(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *req, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - - dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n"); - req->data.length = sizeof(*range); - return zd_mac_get_range(zd_netdev_mac(netdev), range); -} - -static int iw_set_encode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info, - data, extra); -} - -static int iw_get_encode(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info, - data, extra); -} - -static int iw_set_encodeext(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info, - data, extra); -} - -static int iw_get_encodeext(struct net_device *netdev, - struct iw_request_info *info, - union iwreq_data *data, - char *extra) -{ - return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info, - data, extra); -} - -#define WX(x) [(x)-SIOCIWFIRST] - -static const iw_handler zd_standard_iw_handlers[] = { - WX(SIOCGIWNAME) = iw_get_name, - WX(SIOCGIWNICKN) = iw_get_nick, - WX(SIOCSIWFREQ) = iw_set_freq, - WX(SIOCGIWFREQ) = iw_get_freq, - WX(SIOCSIWMODE) = iw_set_mode, - WX(SIOCGIWMODE) = iw_get_mode, - WX(SIOCGIWRANGE) = iw_get_range, - WX(SIOCSIWENCODE) = iw_set_encode, - WX(SIOCGIWENCODE) = iw_get_encode, - WX(SIOCSIWENCODEEXT) = iw_set_encodeext, - WX(SIOCGIWENCODEEXT) = iw_get_encodeext, - WX(SIOCSIWAUTH) = ieee80211_wx_set_auth, - WX(SIOCGIWAUTH) = ieee80211_wx_get_auth, - WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan, - WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results, - WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid, - WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid, - WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap, - WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap, - WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate, - WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate, - WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie, - WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie, - WX(SIOCSIWMLME) = ieee80211softmac_wx_set_mlme, -}; - -static const struct iw_handler_def iw_handler_def = { - .standard = zd_standard_iw_handlers, - .num_standard = ARRAY_SIZE(zd_standard_iw_handlers), - .private = zd_priv_handler, - .num_private = ARRAY_SIZE(zd_priv_handler), - .private_args = zd_priv_args, - .num_private_args = ARRAY_SIZE(zd_priv_args), - .get_wireless_stats = zd_mac_get_wireless_stats, -}; - -struct net_device *zd_netdev_alloc(struct usb_interface *intf) -{ - int r; - struct net_device *netdev; - struct zd_mac *mac; - - netdev = alloc_ieee80211softmac(sizeof(struct zd_mac)); - if (!netdev) { - dev_dbg_f(&intf->dev, "out of memory\n"); - return NULL; - } - - mac = zd_netdev_mac(netdev); - r = zd_mac_init(mac, netdev, intf); - if (r) { - usb_set_intfdata(intf, NULL); - free_ieee80211(netdev); - return NULL; - } - - SET_NETDEV_DEV(netdev, &intf->dev); - - dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags); - dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features); - - netdev->open = zd_mac_open; - netdev->stop = zd_mac_stop; - /* netdev->get_stats = */ - netdev->set_multicast_list = zd_mac_set_multicast_list; - netdev->set_mac_address = zd_mac_set_mac_address; - netdev->wireless_handlers = &iw_handler_def; - /* netdev->ethtool_ops = */ - - return netdev; -} - -void zd_netdev_free(struct net_device *netdev) -{ - if (!netdev) - return; - - zd_mac_clear(zd_netdev_mac(netdev)); - free_ieee80211(netdev); -} - -void zd_netdev_disconnect(struct net_device *netdev) -{ - unregister_netdev(netdev); -} diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.h b/drivers/net/wireless/zd1211rw/zd_netdev.h deleted file mode 100644 index 374a957..0000000 --- a/drivers/net/wireless/zd1211rw/zd_netdev.h +++ /dev/null @@ -1,45 +0,0 @@ -/* zd_netdev.h: Header for net device related functions. - * - * 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 - */ - -#ifndef _ZD_NETDEV_H -#define _ZD_NETDEV_H - -#include -#include -#include - -#define ZD_PRIV_SET_REGDOMAIN (SIOCIWFIRSTPRIV) -#define ZD_PRIV_GET_REGDOMAIN (SIOCIWFIRSTPRIV+1) - -static inline struct ieee80211_device *zd_netdev_ieee80211( - struct net_device *ndev) -{ - return netdev_priv(ndev); -} - -static inline struct net_device *zd_ieee80211_to_netdev( - struct ieee80211_device *ieee) -{ - return ieee->dev; -} - -struct net_device *zd_netdev_alloc(struct usb_interface *intf); -void zd_netdev_free(struct net_device *netdev); - -void zd_netdev_disconnect(struct net_device *netdev); - -#endif /* _ZD_NETDEV_H */ diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c index abe5d38..ec41293 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.c +++ b/drivers/net/wireless/zd1211rw/zd_rf.c @@ -1,4 +1,7 @@ -/* zd_rf.c +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h index 30502f2..79dc103 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf.h +++ b/drivers/net/wireless/zd1211rw/zd_rf.h @@ -1,4 +1,7 @@ -/* zd_rf.h +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c index 006774d..74a8f7a 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c @@ -1,4 +1,7 @@ -/* zd_rf_al2230.c: Functions for the AL2230 RF controller +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c index 73d0bb2..65095d6 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c @@ -1,4 +1,7 @@ -/* zd_rf_al7230b.c: Functions for the AL7230B RF controller +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c index cc70d40..0597d86 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c @@ -1,4 +1,7 @@ -/* zd_rf_rfmd.c: Functions for the RFMD RF controller +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c index 857dcf3..439799b 100644 --- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c +++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c @@ -1,4 +1,7 @@ -/* zd_rf_uw2453.c: Functions for the UW2453 RF controller +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -403,7 +406,7 @@ static int uw2453_init_hw(struct zd_rf *rf) if (r) return r; - if (!intr_status & 0xf) { + if (!(intr_status & 0xf)) { dev_dbg_f(zd_chip_dev(chip), "PLL locked on configuration %d\n", i); found_config = i; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c755b69..7942b15 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1,4 +1,8 @@ -/* zd_usb.c +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake + * Copyright (C) 2006-2007 Michael Wu * * 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 @@ -17,18 +21,16 @@ #include #include -#include #include #include #include #include #include #include -#include +#include #include #include "zd_def.h" -#include "zd_netdev.h" #include "zd_mac.h" #include "zd_usb.h" @@ -55,6 +57,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x13b1, 0x001e), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, @@ -353,18 +356,6 @@ out: spin_unlock(&intr->lock); } -static inline void handle_retry_failed_int(struct urb *urb) -{ - struct zd_usb *usb = urb->context; - struct zd_mac *mac = zd_usb_to_mac(usb); - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - - ieee->stats.tx_errors++; - ieee->ieee_stats.tx_retry_limit_exceeded++; - dev_dbg_f(urb_dev(urb), "retry failed interrupt\n"); -} - - static void int_urb_complete(struct urb *urb) { int r; @@ -400,7 +391,7 @@ static void int_urb_complete(struct urb *urb) handle_regs_int(urb); break; case USB_INT_ID_RETRY_FAILED: - handle_retry_failed_int(urb); + zd_mac_tx_failed(zd_usb_to_hw(urb->context)); break; default: dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, @@ -530,14 +521,10 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, unsigned int length) { int i; - struct zd_mac *mac = zd_usb_to_mac(usb); const struct rx_length_info *length_info; if (length < sizeof(struct rx_length_info)) { /* It's not a complete packet anyhow. */ - struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); - ieee->stats.rx_errors++; - ieee->stats.rx_length_errors++; return; } length_info = (struct rx_length_info *) @@ -561,13 +548,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, n = l+k; if (n > length) return; - zd_mac_rx_irq(mac, buffer+l, k); + zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k); if (i >= 2) return; l = (n+3) & ~3; } } else { - zd_mac_rx_irq(mac, buffer, length); + zd_mac_rx(zd_usb_to_hw(usb), buffer, length); } } @@ -629,7 +616,7 @@ resubmit: usb_submit_urb(urb, GFP_ATOMIC); } -static struct urb *alloc_urb(struct zd_usb *usb) +static struct urb *alloc_rx_urb(struct zd_usb *usb) { struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; @@ -653,7 +640,7 @@ static struct urb *alloc_urb(struct zd_usb *usb) return urb; } -static void free_urb(struct urb *urb) +static void free_rx_urb(struct urb *urb) { if (!urb) return; @@ -671,11 +658,11 @@ int zd_usb_enable_rx(struct zd_usb *usb) dev_dbg_f(zd_usb_dev(usb), "\n"); r = -ENOMEM; - urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); + urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); if (!urbs) goto error; - for (i = 0; i < URBS_COUNT; i++) { - urbs[i] = alloc_urb(usb); + for (i = 0; i < RX_URBS_COUNT; i++) { + urbs[i] = alloc_rx_urb(usb); if (!urbs[i]) goto error; } @@ -688,10 +675,10 @@ int zd_usb_enable_rx(struct zd_usb *usb) goto error; } rx->urbs = urbs; - rx->urbs_count = URBS_COUNT; + rx->urbs_count = RX_URBS_COUNT; spin_unlock_irq(&rx->lock); - for (i = 0; i < URBS_COUNT; i++) { + for (i = 0; i < RX_URBS_COUNT; i++) { r = usb_submit_urb(urbs[i], GFP_KERNEL); if (r) goto error_submit; @@ -699,7 +686,7 @@ int zd_usb_enable_rx(struct zd_usb *usb) return 0; error_submit: - for (i = 0; i < URBS_COUNT; i++) { + for (i = 0; i < RX_URBS_COUNT; i++) { usb_kill_urb(urbs[i]); } spin_lock_irq(&rx->lock); @@ -708,8 +695,8 @@ error_submit: spin_unlock_irq(&rx->lock); error: if (urbs) { - for (i = 0; i < URBS_COUNT; i++) - free_urb(urbs[i]); + for (i = 0; i < RX_URBS_COUNT; i++) + free_rx_urb(urbs[i]); } return r; } @@ -731,7 +718,7 @@ void zd_usb_disable_rx(struct zd_usb *usb) for (i = 0; i < count; i++) { usb_kill_urb(urbs[i]); - free_urb(urbs[i]); + free_rx_urb(urbs[i]); } kfree(urbs); @@ -741,9 +728,142 @@ void zd_usb_disable_rx(struct zd_usb *usb) spin_unlock_irqrestore(&rx->lock, flags); } +/** + * zd_usb_disable_tx - disable transmission + * @usb: the zd1211rw-private USB structure + * + * Frees all URBs in the free list and marks the transmission as disabled. + */ +void zd_usb_disable_tx(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + unsigned long flags; + struct list_head *pos, *n; + + spin_lock_irqsave(&tx->lock, flags); + list_for_each_safe(pos, n, &tx->free_urb_list) { + list_del(pos); + usb_free_urb(list_entry(pos, struct urb, urb_list)); + } + tx->enabled = 0; + tx->submitted_urbs = 0; + /* The stopped state is ignored, relying on ieee80211_wake_queues() + * in a potentionally following zd_usb_enable_tx(). + */ + spin_unlock_irqrestore(&tx->lock, flags); +} + +/** + * zd_usb_enable_tx - enables transmission + * @usb: a &struct zd_usb pointer + * + * This function enables transmission and prepares the &zd_usb_tx data + * structure. + */ +void zd_usb_enable_tx(struct zd_usb *usb) +{ + unsigned long flags; + struct zd_usb_tx *tx = &usb->tx; + + spin_lock_irqsave(&tx->lock, flags); + tx->enabled = 1; + tx->submitted_urbs = 0; + ieee80211_wake_queues(zd_usb_to_hw(usb)); + tx->stopped = 0; + spin_unlock_irqrestore(&tx->lock, flags); +} + +/** + * alloc_tx_urb - provides an tx URB + * @usb: a &struct zd_usb pointer + * + * Allocates a new URB. If possible takes the urb from the free list in + * usb->tx. + */ +static struct urb *alloc_tx_urb(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + unsigned long flags; + struct list_head *entry; + struct urb *urb; + + spin_lock_irqsave(&tx->lock, flags); + if (list_empty(&tx->free_urb_list)) { + urb = usb_alloc_urb(0, GFP_ATOMIC); + goto out; + } + entry = tx->free_urb_list.next; + list_del(entry); + urb = list_entry(entry, struct urb, urb_list); +out: + spin_unlock_irqrestore(&tx->lock, flags); + return urb; +} + +/** + * free_tx_urb - frees a used tx URB + * @usb: a &struct zd_usb pointer + * @urb: URB to be freed + * + * Frees the the transmission URB, which means to put it on the free URB + * list. + */ +static void free_tx_urb(struct zd_usb *usb, struct urb *urb) +{ + struct zd_usb_tx *tx = &usb->tx; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + if (!tx->enabled) { + usb_free_urb(urb); + goto out; + } + list_add(&urb->urb_list, &tx->free_urb_list); +out: + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void tx_dec_submitted_urbs(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + --tx->submitted_urbs; + if (tx->stopped && tx->submitted_urbs <= ZD_USB_TX_LOW) { + ieee80211_wake_queues(zd_usb_to_hw(usb)); + tx->stopped = 0; + } + spin_unlock_irqrestore(&tx->lock, flags); +} + +static void tx_inc_submitted_urbs(struct zd_usb *usb) +{ + struct zd_usb_tx *tx = &usb->tx; + unsigned long flags; + + spin_lock_irqsave(&tx->lock, flags); + ++tx->submitted_urbs; + if (!tx->stopped && tx->submitted_urbs > ZD_USB_TX_HIGH) { + ieee80211_stop_queues(zd_usb_to_hw(usb)); + tx->stopped = 1; + } + spin_unlock_irqrestore(&tx->lock, flags); +} + +/** + * tx_urb_complete - completes the execution of an URB + * @urb: a URB + * + * This function is called if the URB has been transferred to a device or an + * error has happened. + */ static void tx_urb_complete(struct urb *urb) { int r; + struct sk_buff *skb; + struct zd_tx_skb_control_block *cb; + struct zd_usb *usb; switch (urb->status) { case 0: @@ -761,9 +881,12 @@ static void tx_urb_complete(struct urb *urb) goto resubmit; } free_urb: - usb_buffer_free(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); - usb_free_urb(urb); + skb = (struct sk_buff *)urb->context; + zd_mac_tx_to_dev(skb, urb->status); + cb = (struct zd_tx_skb_control_block *)skb->cb; + usb = &zd_hw_mac(cb->hw)->chip.usb; + free_tx_urb(usb, urb); + tx_dec_submitted_urbs(usb); return; resubmit: r = usb_submit_urb(urb, GFP_ATOMIC); @@ -773,43 +896,40 @@ resubmit: } } -/* Puts the frame on the USB endpoint. It doesn't wait for - * completion. The frame must contain the control set. +/** + * zd_usb_tx: initiates transfer of a frame of the device + * + * @usb: the zd1211rw-private USB structure + * @skb: a &struct sk_buff pointer + * + * This function tranmits a frame to the device. It doesn't wait for + * completion. The frame must contain the control set and have all the + * control set information available. + * + * The function returns 0 if the transfer has been successfully initiated. */ -int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length) +int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) { int r; struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; - void *buffer; - urb = usb_alloc_urb(0, GFP_ATOMIC); + urb = alloc_tx_urb(usb); if (!urb) { r = -ENOMEM; goto out; } - buffer = usb_buffer_alloc(zd_usb_to_usbdev(usb), length, GFP_ATOMIC, - &urb->transfer_dma); - if (!buffer) { - r = -ENOMEM; - goto error_free_urb; - } - memcpy(buffer, frame, length); - usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), - buffer, length, tx_urb_complete, NULL); - urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + skb->data, skb->len, tx_urb_complete, skb); r = usb_submit_urb(urb, GFP_ATOMIC); if (r) goto error; + tx_inc_submitted_urbs(usb); return 0; error: - usb_buffer_free(zd_usb_to_usbdev(usb), length, buffer, - urb->transfer_dma); -error_free_urb: - usb_free_urb(urb); + free_tx_urb(usb, urb); out: return r; } @@ -838,16 +958,20 @@ static inline void init_usb_rx(struct zd_usb *usb) static inline void init_usb_tx(struct zd_usb *usb) { - /* FIXME: at this point we will allocate a fixed number of urb's for - * use in a cyclic scheme */ + struct zd_usb_tx *tx = &usb->tx; + spin_lock_init(&tx->lock); + tx->enabled = 0; + tx->stopped = 0; + INIT_LIST_HEAD(&tx->free_urb_list); + tx->submitted_urbs = 0; } -void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, +void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, struct usb_interface *intf) { memset(usb, 0, sizeof(*usb)); usb->intf = usb_get_intf(intf); - usb_set_intfdata(usb->intf, netdev); + usb_set_intfdata(usb->intf, hw); init_usb_interrupt(usb); init_usb_tx(usb); init_usb_rx(usb); @@ -973,7 +1097,7 @@ int zd_usb_init_hw(struct zd_usb *usb) return r; } - r = zd_mac_init_hw(mac); + r = zd_mac_init_hw(mac->hw); if (r) { dev_dbg_f(zd_usb_dev(usb), "couldn't initialize mac. Error number %d\n", r); @@ -987,9 +1111,9 @@ int zd_usb_init_hw(struct zd_usb *usb) static int probe(struct usb_interface *intf, const struct usb_device_id *id) { int r; - struct zd_usb *usb; struct usb_device *udev = interface_to_usbdev(intf); - struct net_device *netdev = NULL; + struct zd_usb *usb; + struct ieee80211_hw *hw = NULL; print_id(udev); @@ -1007,57 +1131,65 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; } - usb_reset_device(interface_to_usbdev(intf)); + r = usb_reset_device(udev); + if (r) { + dev_err(&intf->dev, + "couldn't reset usb device. Error number %d\n", r); + goto error; + } - netdev = zd_netdev_alloc(intf); - if (netdev == NULL) { + hw = zd_mac_alloc_hw(intf); + if (hw == NULL) { r = -ENOMEM; goto error; } - usb = &zd_netdev_mac(netdev)->chip.usb; + usb = &zd_hw_mac(hw)->chip.usb; usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0; - r = zd_mac_preinit_hw(zd_netdev_mac(netdev)); + r = zd_mac_preinit_hw(hw); if (r) { dev_dbg_f(&intf->dev, "couldn't initialize mac. Error number %d\n", r); goto error; } - r = register_netdev(netdev); + r = ieee80211_register_hw(hw); if (r) { dev_dbg_f(&intf->dev, - "couldn't register netdev. Error number %d\n", r); + "couldn't register device. Error number %d\n", r); goto error; } dev_dbg_f(&intf->dev, "successful\n"); - dev_info(&intf->dev,"%s\n", netdev->name); + dev_info(&intf->dev, "%s\n", wiphy_name(hw->wiphy)); return 0; error: usb_reset_device(interface_to_usbdev(intf)); - zd_netdev_free(netdev); + if (hw) { + zd_mac_clear(zd_hw_mac(hw)); + ieee80211_free_hw(hw); + } return r; } static void disconnect(struct usb_interface *intf) { - struct net_device *netdev = zd_intf_to_netdev(intf); + struct ieee80211_hw *hw = zd_intf_to_hw(intf); struct zd_mac *mac; struct zd_usb *usb; /* Either something really bad happened, or we're just dealing with * a DEVICE_INSTALLER. */ - if (netdev == NULL) + if (hw == NULL) return; - mac = zd_netdev_mac(netdev); + mac = zd_hw_mac(hw); usb = &mac->chip.usb; dev_dbg_f(zd_usb_dev(usb), "\n"); - zd_netdev_disconnect(netdev); + ieee80211_unregister_hw(hw); /* Just in case something has gone wrong! */ zd_usb_disable_rx(usb); @@ -1070,12 +1202,13 @@ static void disconnect(struct usb_interface *intf) */ usb_reset_device(interface_to_usbdev(intf)); - zd_netdev_free(netdev); + zd_mac_clear(mac); + ieee80211_free_hw(hw); dev_dbg(&intf->dev, "disconnected\n"); } static struct usb_driver driver = { - .name = "zd1211rw", + .name = KBUILD_MODNAME, .id_table = usb_ids, .probe = probe, .disconnect = disconnect, diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 961a7a1..049f8b9 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h @@ -1,4 +1,7 @@ -/* zd_usb.h: Header for USB interface implemented by ZD1211 chip +/* ZD1211 USB-WLAN driver for Linux + * + * Copyright (C) 2005-2007 Ulrich Kunitz + * Copyright (C) 2006-2007 Daniel Drake * * 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 @@ -26,6 +29,9 @@ #include "zd_def.h" +#define ZD_USB_TX_HIGH 5 +#define ZD_USB_TX_LOW 2 + enum devicetype { DEVICE_ZD1211 = 0, DEVICE_ZD1211B = 1, @@ -165,7 +171,7 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) return (struct usb_int_regs *)intr->read_regs.buffer; } -#define URBS_COUNT 5 +#define RX_URBS_COUNT 5 struct zd_usb_rx { spinlock_t lock; @@ -176,8 +182,21 @@ struct zd_usb_rx { int urbs_count; }; +/** + * struct zd_usb_tx - structure used for transmitting frames + * @lock: lock for transmission + * @free_urb_list: list of free URBs, contains all the URBs, which can be used + * @submitted_urbs: atomic integer that counts the URBs having sent to the + * device, which haven't been completed + * @enabled: enabled flag, indicates whether tx is enabled + * @stopped: indicates whether higher level tx queues are stopped + */ struct zd_usb_tx { spinlock_t lock; + struct list_head free_urb_list; + int submitted_urbs; + int enabled; + int stopped; }; /* Contains the usb parts. The structure doesn't require a lock because intf @@ -198,17 +217,17 @@ static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb) return interface_to_usbdev(usb->intf); } -static inline struct net_device *zd_intf_to_netdev(struct usb_interface *intf) +static inline struct ieee80211_hw *zd_intf_to_hw(struct usb_interface *intf) { return usb_get_intfdata(intf); } -static inline struct net_device *zd_usb_to_netdev(struct zd_usb *usb) +static inline struct ieee80211_hw *zd_usb_to_hw(struct zd_usb *usb) { - return zd_intf_to_netdev(usb->intf); + return zd_intf_to_hw(usb->intf); } -void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, +void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, struct usb_interface *intf); int zd_usb_init_hw(struct zd_usb *usb); void zd_usb_clear(struct zd_usb *usb); @@ -221,7 +240,10 @@ void zd_usb_disable_int(struct zd_usb *usb); int zd_usb_enable_rx(struct zd_usb *usb); void zd_usb_disable_rx(struct zd_usb *usb); -int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length); +void zd_usb_enable_tx(struct zd_usb *usb); +void zd_usb_disable_tx(struct zd_usb *usb); + +int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb); int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, const zd_addr_t *addresses, unsigned int count); diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c index f145d8a..b8b7cb0 100644 --- a/drivers/ssb/b43_pci_bridge.c +++ b/drivers/ssb/b43_pci_bridge.c @@ -27,6 +27,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4328) }, { 0, }, }; MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 85a2054..9028ed5 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -872,14 +872,22 @@ EXPORT_SYMBOL(ssb_clockspeed); static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev) { + u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV; + /* The REJECT bit changed position in TMSLOW between * Backplane revisions. */ - switch (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV) { + switch (rev) { case SSB_IDLOW_SSBREV_22: return SSB_TMSLOW_REJECT_22; case SSB_IDLOW_SSBREV_23: return SSB_TMSLOW_REJECT_23; + case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */ + case SSB_IDLOW_SSBREV_25: /* same here */ + case SSB_IDLOW_SSBREV_26: /* same here */ + case SSB_IDLOW_SSBREV_27: /* same here */ + return SSB_TMSLOW_REJECT_23; /* this is a guess */ default: + printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); WARN_ON(1); } return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23); diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 0ab095c..9777dcb 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -212,29 +212,29 @@ static inline u8 ssb_crc8(u8 crc, u8 data) return t[crc ^ data]; } -static u8 ssb_sprom_crc(const u16 *sprom) +static u8 ssb_sprom_crc(const u16 *sprom, u16 size) { int word; u8 crc = 0xFF; - for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) { + for (word = 0; word < size - 1; word++) { crc = ssb_crc8(crc, sprom[word] & 0x00FF); crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8); } - crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF); + crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF); crc ^= 0xFF; return crc; } -static int sprom_check_crc(const u16 *sprom) +static int sprom_check_crc(const u16 *sprom, u16 size) { u8 crc; u8 expected_crc; u16 tmp; - crc = ssb_sprom_crc(sprom); - tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC; + crc = ssb_sprom_crc(sprom, size); + tmp = sprom[size - 1] & SSB_SPROM_REVISION_CRC; expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; if (crc != expected_crc) return -EPROTO; @@ -246,7 +246,7 @@ static void sprom_do_read(struct ssb_bus *bus, u16 *sprom) { int i; - for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) + for (i = 0; i < bus->sprom_size; i++) sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2)); } @@ -255,6 +255,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) struct pci_dev *pdev = bus->host_pci; int i, err; u32 spromctl; + u16 size = bus->sprom_size; ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n"); err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl); @@ -266,12 +267,12 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom) goto err_ctlreg; ssb_printk(KERN_NOTICE PFX "[ 0%%"); msleep(500); - for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) { - if (i == SSB_SPROMSIZE_WORDS / 4) + for (i = 0; i < size; i++) { + if (i == size / 4) ssb_printk("25%%"); - else if (i == SSB_SPROMSIZE_WORDS / 2) + else if (i == size / 2) ssb_printk("50%%"); - else if (i == (SSB_SPROMSIZE_WORDS / 4) * 3) + else if (i == (size * 3) / 4) ssb_printk("75%%"); else if (i % 2) ssb_printk("."); @@ -296,38 +297,38 @@ err_ctlreg: return err; } -static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in) +static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in) { int i; u16 v; + u16 loc[3]; - SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0); - SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0); - SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0); + if (out->revision == 3) { /* rev 3 moved MAC */ + loc[0] = SSB_SPROM3_IL0MAC; + loc[1] = SSB_SPROM3_ET0MAC; + loc[2] = SSB_SPROM3_ET1MAC; + } else { + loc[0] = SSB_SPROM1_IL0MAC; + loc[1] = SSB_SPROM1_ET0MAC; + loc[2] = SSB_SPROM1_ET1MAC; + } for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM1_IL0MAC) + i]; + v = in[SPOFF(loc[0]) + i]; *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM1_ET0MAC) + i]; + v = in[SPOFF(loc[1]) + i]; *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); } for (i = 0; i < 3; i++) { - v = in[SPOFF(SSB_SPROM1_ET1MAC) + i]; + v = in[SPOFF(loc[2]) + i]; *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); } SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0); SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A, SSB_SPROM1_ETHPHY_ET1A_SHIFT); - SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14); - SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15); - SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0); SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE, SSB_SPROM1_BINF_CCODE_SHIFT); - SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA, - SSB_SPROM1_BINF_ANTA_SHIFT); - SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG, - SSB_SPROM1_BINF_ANTBG_SHIFT); SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0); SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0); SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0); @@ -350,97 +351,75 @@ static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in) SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0); SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG, SSB_SPROM1_AGAIN_BG_SHIFT); - for (i = 0; i < 4; i++) { - v = in[SPOFF(SSB_SPROM1_OEM) + i]; - *(((__le16 *)out->oem) + i) = cpu_to_le16(v); - } } -static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in) +static void sprom_extract_r4(struct ssb_sprom *out, const u16 *in) { int i; u16 v; - SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0); - SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0); - SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO, - SSB_SPROM2_MAXP_A_LO_SHIFT); - SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0); - SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0); - SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0); - SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0); - SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0); - SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0); - SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0); - for (i = 0; i < 4; i++) { - v = in[SPOFF(SSB_SPROM2_CCODE) + i]; - *(((__le16 *)out->country_str) + i) = cpu_to_le16(v); + /* extract the equivalent of the r1 variables */ + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM4_IL0MAC) + i]; + *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); } + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM4_ET0MAC) + i]; + *(((__be16 *)out->et0mac) + i) = cpu_to_be16(v); + } + for (i = 0; i < 3; i++) { + v = in[SPOFF(SSB_SPROM4_ET1MAC) + i]; + *(((__be16 *)out->et1mac) + i) = cpu_to_be16(v); + } + SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0); + SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A, + SSB_SPROM4_ETHPHY_ET1A_SHIFT); + SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); + SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); + SPEX(antenna_gain_a, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_0, 0); + SPEX(antenna_gain_bg, SSB_SPROM4_AGAIN, SSB_SPROM4_AGAIN_1, + SSB_SPROM4_AGAIN_1_SHIFT); + SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0); + SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG, + SSB_SPROM4_ITSSI_BG_SHIFT); + SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0); + SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A, + SSB_SPROM4_ITSSI_A_SHIFT); + SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0); + SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1, + SSB_SPROM4_GPIOA_P1_SHIFT); + SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0); + SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3, + SSB_SPROM4_GPIOB_P3_SHIFT); + /* TODO - get remaining rev 4 stuff needed */ } -static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in) -{ - out->ofdmapo = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8; - out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8; - out->ofdmapo <<= 16; - out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8; - out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8; - - out->ofdmalpo = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8; - out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8; - out->ofdmalpo <<= 16; - out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8; - out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8; - - out->ofdmahpo = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8; - out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8; - out->ofdmahpo <<= 16; - out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8; - out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8; - - SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON, - SSB_SPROM3_GPIOLDC_ON_SHIFT); - SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF, - SSB_SPROM3_GPIOLDC_OFF_SHIFT); - SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0); - SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M, - SSB_SPROM3_CCKPO_2M_SHIFT); - SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M, - SSB_SPROM3_CCKPO_55M_SHIFT); - SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M, - SSB_SPROM3_CCKPO_11M_SHIFT); - - out->ofdmgpo = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8; - out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8; - out->ofdmgpo <<= 16; - out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8; - out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8; -} - -static int sprom_extract(struct ssb_bus *bus, - struct ssb_sprom *out, const u16 *in) +static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, + const u16 *in, u16 size) { memset(out, 0, sizeof(*out)); - SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0); - SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC, - SSB_SPROM_REVISION_CRC_SHIFT); - + out->revision = in[size - 1] & 0x00FF; + ssb_printk(KERN_INFO PFX "SPROM revision %d detected.\n", out->revision); if ((bus->chip_id & 0xFF00) == 0x4400) { /* Workaround: The BCM44XX chip has a stupid revision * number stored in the SPROM. * Always extract r1. */ - sprom_extract_r1(&out->r1, in); + out->revision = 1; + sprom_extract_r123(out, in); + } else if (bus->chip_id == 0x4321) { + /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */ + out->revision = 4; + sprom_extract_r4(out, in); } else { if (out->revision == 0) goto unsupported; - if (out->revision >= 1 && out->revision <= 3) - sprom_extract_r1(&out->r1, in); - if (out->revision >= 2 && out->revision <= 3) - sprom_extract_r2(&out->r2, in); - if (out->revision == 3) - sprom_extract_r3(&out->r3, in); - if (out->revision >= 4) + if (out->revision >= 1 && out->revision <= 3) { + sprom_extract_r123(out, in); + } + if (out->revision == 4) + sprom_extract_r4(out, in); + if (out->revision >= 5) goto unsupported; } @@ -448,7 +427,7 @@ static int sprom_extract(struct ssb_bus *bus, unsupported: ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d " "detected. Will extract v1\n", out->revision); - sprom_extract_r1(&out->r1, in); + sprom_extract_r123(out, in); return 0; } @@ -458,16 +437,31 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus, int err = -ENOMEM; u16 *buf; - buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL); if (!buf) goto out; + bus->sprom_size = SSB_SPROMSIZE_WORDS_R123; sprom_do_read(bus, buf); - err = sprom_check_crc(buf); + err = sprom_check_crc(buf, bus->sprom_size); if (err) { - ssb_printk(KERN_WARNING PFX - "WARNING: Invalid SPROM CRC (corrupt SPROM)\n"); + /* check for rev 4 sprom - has special signature */ + if (buf [32] == 0x5372) { + ssb_printk(KERN_WARNING PFX "Extracting a rev 4" + " SPROM\n"); + kfree(buf); + buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), + GFP_KERNEL); + if (!buf) + goto out; + bus->sprom_size = SSB_SPROMSIZE_WORDS_R4; + sprom_do_read(bus, buf); + err = sprom_check_crc(buf, bus->sprom_size); + } + if (err) + ssb_printk(KERN_WARNING PFX "WARNING: Invalid" + " SPROM CRC (corrupt SPROM)\n"); } - err = sprom_extract(bus, sprom, buf); + err = sprom_extract(bus, sprom, buf, bus->sprom_size); kfree(buf); out: @@ -581,29 +575,28 @@ const struct ssb_bus_ops ssb_pci_ops = { .write32 = ssb_pci_write32, }; -static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) +static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, u16 size) { int i, pos = 0; - for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) { + for (i = 0; i < size; i++) pos += snprintf(buf + pos, buf_len - pos - 1, "%04X", swab16(sprom[i]) & 0xFFFF); - } pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); return pos + 1; } -static int hex2sprom(u16 *sprom, const char *dump, size_t len) +static int hex2sprom(u16 *sprom, const char *dump, size_t len, u16 size) { char tmp[5] = { 0 }; int cnt = 0; unsigned long parsed; - if (len < SSB_SPROMSIZE_BYTES * 2) + if (len < size * 2) return -EINVAL; - while (cnt < SSB_SPROMSIZE_WORDS) { + while (cnt < size) { memcpy(tmp, dump, 4); dump += 4; parsed = simple_strtoul(tmp, NULL, 16); @@ -627,7 +620,7 @@ static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev, if (!bus) goto out; err = -ENOMEM; - sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL); if (!sprom) goto out; @@ -640,7 +633,7 @@ static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev, sprom_do_read(bus, sprom); mutex_unlock(&bus->pci_sprom_mutex); - count = sprom2hex(sprom, buf, PAGE_SIZE); + count = sprom2hex(sprom, buf, PAGE_SIZE, bus->sprom_size); err = 0; out_kfree: @@ -662,15 +655,15 @@ static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev, if (!bus) goto out; err = -ENOMEM; - sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL); + sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL); if (!sprom) goto out; - err = hex2sprom(sprom, buf, count); + err = hex2sprom(sprom, buf, count, bus->sprom_size); if (err) { err = -EINVAL; goto out_kfree; } - err = sprom_check_crc(sprom); + err = sprom_check_crc(sprom, bus->sprom_size); if (err) { err = -EINVAL; goto out_kfree; diff --git a/include/asm-powerpc/pasemi_dma.h b/include/asm-powerpc/pasemi_dma.h new file mode 100644 index 0000000..b4526ff --- /dev/null +++ b/include/asm-powerpc/pasemi_dma.h @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2006 PA Semi, Inc + * + * Hardware register layout and descriptor formats for the on-board + * DMA engine on PA Semi PWRficient. Used by ethernet, function and security + * drivers. + * + * 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. + * + * 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 ASM_PASEMI_DMA_H +#define ASM_PASEMI_DMA_H + +/* status register layout in IOB region, at 0xfb800000 */ +struct pasdma_status { + u64 rx_sta[64]; /* RX channel status */ + u64 tx_sta[20]; /* TX channel status */ +}; + + +/* All these registers live in the PCI configuration space for the DMA PCI + * device. Use the normal PCI config access functions for them. + */ +enum { + PAS_DMA_CAP_TXCH = 0x44, /* Transmit Channel Info */ + PAS_DMA_CAP_RXCH = 0x48, /* Transmit Channel Info */ + PAS_DMA_CAP_IFI = 0x4c, /* Interface Info */ + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */ + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */ + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */ + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */ +}; + + +#define PAS_DMA_CAP_TXCH_TCHN_M 0x00ff0000 /* # of TX channels */ +#define PAS_DMA_CAP_TXCH_TCHN_S 16 + +#define PAS_DMA_CAP_RXCH_RCHN_M 0x00ff0000 /* # of RX channels */ +#define PAS_DMA_CAP_RXCH_RCHN_S 16 + +#define PAS_DMA_CAP_IFI_IOFF_M 0xff000000 /* Cfg reg for intf pointers */ +#define PAS_DMA_CAP_IFI_IOFF_S 24 +#define PAS_DMA_CAP_IFI_NIN_M 0x00ff0000 /* # of interfaces */ +#define PAS_DMA_CAP_IFI_NIN_S 16 + +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */ +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */ +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */ +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */ + + +/* Per-interface and per-channel registers */ +#define _PAS_DMA_RXINT_STRIDE 0x20 +#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001 +#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002 +#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008 +#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010 +#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020 +#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040 +#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800 +#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000 +#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000 +#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000 +#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000 +#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 +#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 +#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 +#define PAS_DMA_RXINT_CFG(i) (0x204+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_CFG_RBP 0x80000000 +#define PAS_DMA_RXINT_CFG_ITRR 0x40000000 +#define PAS_DMA_RXINT_CFG_DHL_M 0x07000000 +#define PAS_DMA_RXINT_CFG_DHL_S 24 +#define PAS_DMA_RXINT_CFG_DHL(x) (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \ + PAS_DMA_RXINT_CFG_DHL_M) +#define PAS_DMA_RXINT_CFG_ITR 0x00400000 +#define PAS_DMA_RXINT_CFG_LW 0x00200000 +#define PAS_DMA_RXINT_CFG_L2 0x00100000 +#define PAS_DMA_RXINT_CFG_HEN 0x00080000 +#define PAS_DMA_RXINT_CFG_WIF 0x00000002 +#define PAS_DMA_RXINT_CFG_WIL 0x00000001 + +#define PAS_DMA_RXINT_INCR(i) (0x210+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_INCR_INCR_M 0x0000ffff +#define PAS_DMA_RXINT_INCR_INCR_S 0 +#define PAS_DMA_RXINT_INCR_INCR(x) ((x) & 0x0000ffff) +#define PAS_DMA_RXINT_BASEL(i) (0x218+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_BASEL_BRBL(x) ((x) & ~0x3f) +#define PAS_DMA_RXINT_BASEU(i) (0x21c+(i)*_PAS_DMA_RXINT_STRIDE) +#define PAS_DMA_RXINT_BASEU_BRBH(x) ((x) & 0xfff) +#define PAS_DMA_RXINT_BASEU_SIZ_M 0x3fff0000 /* # of cache lines worth of buffer ring */ +#define PAS_DMA_RXINT_BASEU_SIZ_S 16 /* 0 = 16K */ +#define PAS_DMA_RXINT_BASEU_SIZ(x) (((x) << PAS_DMA_RXINT_BASEU_SIZ_S) & \ + PAS_DMA_RXINT_BASEU_SIZ_M) + + +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */ +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */ +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */ +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */ +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */ +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */ +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */ +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */ +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE) +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */ +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */ +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */ +#define PAS_DMA_TXCHAN_TCMDSTA_SZ 0x00000800 +#define PAS_DMA_TXCHAN_TCMDSTA_DB 0x00000400 +#define PAS_DMA_TXCHAN_TCMDSTA_DE 0x00000200 +#define PAS_DMA_TXCHAN_TCMDSTA_DA 0x00000100 +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE) +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */ +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2 +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \ + PAS_DMA_TXCHAN_CFG_TATTR_M) +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0 +#define PAS_DMA_TXCHAN_CFG_WT_S 6 +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \ + PAS_DMA_TXCHAN_CFG_WT_M) +#define PAS_DMA_TXCHAN_CFG_TRD 0x00010000 /* translate data */ +#define PAS_DMA_TXCHAN_CFG_TRR 0x00008000 /* translate rings */ +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */ +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */ +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */ +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE) +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE) +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0 +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0 +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \ + PAS_DMA_TXCHAN_BASEL_BRBL_M) +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE) +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0 +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \ + PAS_DMA_TXCHAN_BASEU_BRBH_M) +/* # of cache lines worth of buffer ring */ +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000 +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \ + PAS_DMA_TXCHAN_BASEU_SIZ_M) + +#define _PAS_DMA_RXCHAN_STRIDE 0x20 /* Size per channel */ +#define _PAS_DMA_RXCHAN_CCMDSTA 0x800 /* Command / Status */ +#define _PAS_DMA_RXCHAN_CFG 0x804 /* Configuration */ +#define _PAS_DMA_RXCHAN_INCR 0x810 /* Descriptor increment */ +#define _PAS_DMA_RXCHAN_CNT 0x814 /* Descriptor count/offset */ +#define _PAS_DMA_RXCHAN_BASEL 0x818 /* Descriptor ring base (low) */ +#define _PAS_DMA_RXCHAN_BASEU 0x81c /* (high) */ +#define PAS_DMA_RXCHAN_CCMDSTA(c) (0x800+(c)*_PAS_DMA_RXCHAN_STRIDE) +#define PAS_DMA_RXCHAN_CCMDSTA_EN 0x00000001 /* Enabled */ +#define PAS_DMA_RXCHAN_CCMDSTA_ST 0x00000002 /* Stop interface */ +#define PAS_DMA_RXCHAN_CCMDSTA_ACT 0x00010000 /* Active */ +#define PAS_DMA_RXCHAN_CCMDSTA_DU 0x00020000 +#define PAS_DMA_RXCHAN_CCMDSTA_OD 0x00002000 +#define PAS_DMA_RXCHAN_CCMDSTA_FD 0x00001000 +#define PAS_DMA_RXCHAN_CCMDSTA_DT 0x00000800 +#define PAS_DMA_RXCHAN_CFG(c) (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE) +#define PAS_DMA_RXCHAN_CFG_CTR 0x00000400 +#define PAS_DMA_RXCHAN_CFG_HBU_M 0x00000380 +#define PAS_DMA_RXCHAN_CFG_HBU_S 7 +#define PAS_DMA_RXCHAN_CFG_HBU(x) (((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \ + PAS_DMA_RXCHAN_CFG_HBU_M) +#define PAS_DMA_RXCHAN_INCR(c) (0x810+(c)*_PAS_DMA_RXCHAN_STRIDE) +#define PAS_DMA_RXCHAN_BASEL(c) (0x818+(c)*_PAS_DMA_RXCHAN_STRIDE) +#define PAS_DMA_RXCHAN_BASEL_BRBL_M 0xffffffc0 +#define PAS_DMA_RXCHAN_BASEL_BRBL_S 0 +#define PAS_DMA_RXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_RXCHAN_BASEL_BRBL_S) & \ + PAS_DMA_RXCHAN_BASEL_BRBL_M) +#define PAS_DMA_RXCHAN_BASEU(c) (0x81c+(c)*_PAS_DMA_RXCHAN_STRIDE) +#define PAS_DMA_RXCHAN_BASEU_BRBH_M 0x00000fff +#define PAS_DMA_RXCHAN_BASEU_BRBH_S 0 +#define PAS_DMA_RXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_RXCHAN_BASEU_BRBH_S) & \ + PAS_DMA_RXCHAN_BASEU_BRBH_M) +/* # of cache lines worth of buffer ring */ +#define PAS_DMA_RXCHAN_BASEU_SIZ_M 0x3fff0000 +#define PAS_DMA_RXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */ +#define PAS_DMA_RXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_RXCHAN_BASEU_SIZ_S) & \ + PAS_DMA_RXCHAN_BASEU_SIZ_M) + +#define PAS_STATUS_PCNT_M 0x000000000000ffffull +#define PAS_STATUS_PCNT_S 0 +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull +#define PAS_STATUS_DCNT_S 16 +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull +#define PAS_STATUS_BPCNT_S 32 +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull +#define PAS_STATUS_TIMER 0x1000000000000000ull +#define PAS_STATUS_ERROR 0x2000000000000000ull +#define PAS_STATUS_SOFT 0x4000000000000000ull +#define PAS_STATUS_INT 0x8000000000000000ull + +#define PAS_IOB_COM_PKTHDRCNT 0x120 +#define PAS_IOB_COM_PKTHDRCNT_PKTHDR1_M 0x0fff0000 +#define PAS_IOB_COM_PKTHDRCNT_PKTHDR1_S 16 +#define PAS_IOB_COM_PKTHDRCNT_PKTHDR0_M 0x00000fff +#define PAS_IOB_COM_PKTHDRCNT_PKTHDR0_S 0 + +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4) +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0 +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \ + PAS_IOB_DMA_RXCH_CFG_CNTTH_M) +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4) +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0 +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \ + PAS_IOB_DMA_TXCH_CFG_CNTTH_M) +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4) +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000 +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0 +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\ + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4) +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000 +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0 +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\ + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4) +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000 +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16 +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \ + PAS_IOB_DMA_RXCH_RESET_PCNT_M) +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020 +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010 +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008 +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004 +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002 +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001 +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4) +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000 +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16 +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \ + PAS_IOB_DMA_TXCH_RESET_PCNT_M) +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020 +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010 +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008 +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004 +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002 +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001 + +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700 +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0 +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \ + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M) + +/* Transmit descriptor fields */ +#define XCT_MACTX_T 0x8000000000000000ull +#define XCT_MACTX_ST 0x4000000000000000ull +#define XCT_MACTX_NORES 0x0000000000000000ull +#define XCT_MACTX_8BRES 0x1000000000000000ull +#define XCT_MACTX_24BRES 0x2000000000000000ull +#define XCT_MACTX_40BRES 0x3000000000000000ull +#define XCT_MACTX_I 0x0800000000000000ull +#define XCT_MACTX_O 0x0400000000000000ull +#define XCT_MACTX_E 0x0200000000000000ull +#define XCT_MACTX_VLAN_M 0x0180000000000000ull +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull +#define XCT_MACTX_CRC_M 0x0060000000000000ull +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull +#define XCT_MACTX_SS 0x0010000000000000ull +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull +#define XCT_MACTX_LLEN_S 32ull +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \ + XCT_MACTX_LLEN_M) +#define XCT_MACTX_IPH_M 0x00000000f8000000ull +#define XCT_MACTX_IPH_S 27ull +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \ + XCT_MACTX_IPH_M) +#define XCT_MACTX_IPO_M 0x0000000007c00000ull +#define XCT_MACTX_IPO_S 22ull +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \ + XCT_MACTX_IPO_M) +#define XCT_MACTX_CSUM_M 0x0000000000000060ull +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull +#define XCT_MACTX_V6 0x0000000000000010ull +#define XCT_MACTX_C 0x0000000000000004ull +#define XCT_MACTX_AL2 0x0000000000000002ull + +/* Receive descriptor fields */ +#define XCT_MACRX_T 0x8000000000000000ull +#define XCT_MACRX_ST 0x4000000000000000ull +#define XCT_MACRX_RR_M 0x3000000000000000ull +#define XCT_MACRX_RR_NORES 0x0000000000000000ull +#define XCT_MACRX_RR_8BRES 0x1000000000000000ull +#define XCT_MACRX_O 0x0400000000000000ull +#define XCT_MACRX_E 0x0200000000000000ull +#define XCT_MACRX_FF 0x0100000000000000ull +#define XCT_MACRX_PF 0x0080000000000000ull +#define XCT_MACRX_OB 0x0040000000000000ull +#define XCT_MACRX_OD 0x0020000000000000ull +#define XCT_MACRX_FS 0x0010000000000000ull +#define XCT_MACRX_NB_M 0x000fc00000000000ull +#define XCT_MACRX_NB_S 46ULL +#define XCT_MACRX_NB(x) ((((long)(x)) << XCT_MACRX_NB_S) & \ + XCT_MACRX_NB_M) +#define XCT_MACRX_LLEN_M 0x00003fff00000000ull +#define XCT_MACRX_LLEN_S 32ULL +#define XCT_MACRX_LLEN(x) ((((long)(x)) << XCT_MACRX_LLEN_S) & \ + XCT_MACRX_LLEN_M) +#define XCT_MACRX_CRC 0x0000000080000000ull +#define XCT_MACRX_LEN_M 0x0000000060000000ull +#define XCT_MACRX_LEN_TOOSHORT 0x0000000020000000ull +#define XCT_MACRX_LEN_BELOWMIN 0x0000000040000000ull +#define XCT_MACRX_LEN_TRUNC 0x0000000060000000ull +#define XCT_MACRX_CAST_M 0x0000000018000000ull +#define XCT_MACRX_CAST_UNI 0x0000000000000000ull +#define XCT_MACRX_CAST_MULTI 0x0000000008000000ull +#define XCT_MACRX_CAST_BROAD 0x0000000010000000ull +#define XCT_MACRX_CAST_PAUSE 0x0000000018000000ull +#define XCT_MACRX_VLC_M 0x0000000006000000ull +#define XCT_MACRX_FM 0x0000000001000000ull +#define XCT_MACRX_HTY_M 0x0000000000c00000ull +#define XCT_MACRX_HTY_IPV4_OK 0x0000000000000000ull +#define XCT_MACRX_HTY_IPV6 0x0000000000400000ull +#define XCT_MACRX_HTY_IPV4_BAD 0x0000000000800000ull +#define XCT_MACRX_HTY_NONIP 0x0000000000c00000ull +#define XCT_MACRX_IPP_M 0x00000000003f0000ull +#define XCT_MACRX_IPP_S 16 +#define XCT_MACRX_CSUM_M 0x000000000000ffffull +#define XCT_MACRX_CSUM_S 0 + +#define XCT_PTR_T 0x8000000000000000ull +#define XCT_PTR_LEN_M 0x7ffff00000000000ull +#define XCT_PTR_LEN_S 44 +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \ + XCT_PTR_LEN_M) +#define XCT_PTR_ADDR_M 0x00000fffffffffffull +#define XCT_PTR_ADDR_S 0 +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \ + XCT_PTR_ADDR_M) + +/* Receive interface 8byte result fields */ +#define XCT_RXRES_8B_L4O_M 0xff00000000000000ull +#define XCT_RXRES_8B_L4O_S 56 +#define XCT_RXRES_8B_RULE_M 0x00ffff0000000000ull +#define XCT_RXRES_8B_RULE_S 40 +#define XCT_RXRES_8B_EVAL_M 0x000000ffff000000ull +#define XCT_RXRES_8B_EVAL_S 24 +#define XCT_RXRES_8B_HTYPE_M 0x0000000000f00000ull +#define XCT_RXRES_8B_HASH_M 0x00000000000fffffull +#define XCT_RXRES_8B_HASH_S 0 + +/* Receive interface buffer fields */ +#define XCT_RXB_LEN_M 0x0ffff00000000000ull +#define XCT_RXB_LEN_S 44 +#define XCT_RXB_LEN(x) ((((long)(x)) << XCT_RXB_LEN_S) & \ + XCT_RXB_LEN_M) +#define XCT_RXB_ADDR_M 0x00000fffffffffffull +#define XCT_RXB_ADDR_S 0 +#define XCT_RXB_ADDR(x) ((((long)(x)) << XCT_RXB_ADDR_S) & \ + XCT_RXB_ADDR_M) + +/* Copy descriptor fields */ +#define XCT_COPY_T 0x8000000000000000ull +#define XCT_COPY_ST 0x4000000000000000ull +#define XCT_COPY_RR_M 0x3000000000000000ull +#define XCT_COPY_RR_NORES 0x0000000000000000ull +#define XCT_COPY_RR_8BRES 0x1000000000000000ull +#define XCT_COPY_RR_24BRES 0x2000000000000000ull +#define XCT_COPY_RR_40BRES 0x3000000000000000ull +#define XCT_COPY_I 0x0800000000000000ull +#define XCT_COPY_O 0x0400000000000000ull +#define XCT_COPY_E 0x0200000000000000ull +#define XCT_COPY_STY_ZERO 0x01c0000000000000ull +#define XCT_COPY_DTY_PREF 0x0038000000000000ull +#define XCT_COPY_LLEN_M 0x0007ffff00000000ull +#define XCT_COPY_LLEN_S 32 +#define XCT_COPY_LLEN(x) ((((long)(x)) << XCT_COPY_LLEN_S) & \ + XCT_COPY_LLEN_M) +#define XCT_COPY_SE 0x0000000000000001ull + +/* Control descriptor fields */ +#define CTRL_CMD_T 0x8000000000000000ull +#define CTRL_CMD_META_EVT 0x2000000000000000ull +#define CTRL_CMD_O 0x0400000000000000ull +#define CTRL_CMD_REG_M 0x000000000000000full +#define CTRL_CMD_REG_S 0 +#define CTRL_CMD_REG(x) ((((long)(x)) << CTRL_CMD_REG_S) & \ + CTRL_CMD_REG_M) + + + +/* Prototypes for the shared DMA functions in the platform code. */ + +/* DMA TX Channel type. Right now only limitations used are event types 0/1, + * for event-triggered DMA transactions. + */ + +enum pasemi_dmachan_type { + RXCHAN = 0, /* Any RX chan */ + TXCHAN = 1, /* Any TX chan */ + TXCHAN_EVT0 = 0x1001, /* TX chan in event class 0 (chan 0-9) */ + TXCHAN_EVT1 = 0x2001, /* TX chan in event class 1 (chan 10-19) */ +}; + +struct pasemi_dmachan { + int chno; /* Channel number */ + enum pasemi_dmachan_type chan_type; /* TX / RX */ + u64 *status; /* Ptr to cacheable status */ + int irq; /* IRQ used by channel */ + unsigned int ring_size; /* size of allocated ring */ + dma_addr_t ring_dma; /* DMA address for ring */ + u64 *ring_virt; /* Virt address for ring */ + void *priv; /* Ptr to start of client struct */ +}; + +/* Read/write the different registers in the I/O Bridge, Ethernet + * and DMA Controller + */ +extern unsigned int pasemi_read_iob_reg(unsigned int reg); +extern void pasemi_write_iob_reg(unsigned int reg, unsigned int val); + +extern unsigned int pasemi_read_mac_reg(int intf, unsigned int reg); +extern void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val); + +extern unsigned int pasemi_read_dma_reg(unsigned int reg); +extern void pasemi_write_dma_reg(unsigned int reg, unsigned int val); + +/* Channel management routines */ + +extern void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type, + int total_size, int offset); +extern void pasemi_dma_free_chan(struct pasemi_dmachan *chan); + +extern void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, + const u32 cmdsta); +extern int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan); + +/* Common routines to allocate rings and buffers */ + +extern int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size); +extern void pasemi_dma_free_ring(struct pasemi_dmachan *chan); + +extern void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size, + dma_addr_t *handle); +extern void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size, + dma_addr_t *handle); + +/* Initialize the library, must be called before any other functions */ +extern int pasemi_dma_init(void); + +#endif /* ASM_PASEMI_DMA_H */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 111aa10..290f84c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1943,6 +1943,7 @@ #define PCI_DEVICE_ID_NX2_5706 0x164a #define PCI_DEVICE_ID_NX2_5708 0x164c #define PCI_DEVICE_ID_TIGON3_5702FE 0x164d +#define PCI_DEVICE_ID_NX2_57710 0x164e #define PCI_DEVICE_ID_TIGON3_5705 0x1653 #define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 #define PCI_DEVICE_ID_TIGON3_5720 0x1658 @@ -2106,6 +2107,8 @@ #define PCI_DEVICE_ID_HERC_WIN 0x5732 #define PCI_DEVICE_ID_HERC_UNI 0x5832 +#define PCI_VENDOR_ID_RDC 0x17f3 + #define PCI_VENDOR_ID_SITECOM 0x182d #define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069 diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 2b5c312..a21ab29 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -15,22 +15,14 @@ struct pcmcia_device; struct ssb_bus; struct ssb_driver; - -struct ssb_sprom_r1 { - u16 pci_spid; /* Subsystem Product ID for PCI */ - u16 pci_svid; /* Subsystem Vendor ID for PCI */ - u16 pci_pid; /* Product ID for PCI */ +struct ssb_sprom { + u8 revision; u8 il0mac[6]; /* MAC address for 802.11b/g */ u8 et0mac[6]; /* MAC address for Ethernet */ u8 et1mac[6]; /* MAC address for 802.11a */ - u8 et0phyaddr:5; /* MII address for enet0 */ - u8 et1phyaddr:5; /* MII address for enet1 */ - u8 et0mdcport:1; /* MDIO for enet0 */ - u8 et1mdcport:1; /* MDIO for enet1 */ - u8 board_rev; /* Board revision */ - u8 country_code:4; /* Country Code */ - u8 antenna_a:2; /* Antenna 0/1 available for A-PHY */ - u8 antenna_bg:2; /* Antenna 0/1 available for B-PHY and G-PHY */ + u8 et0phyaddr; /* MII address for enet0 */ + u8 et1phyaddr; /* MII address for enet1 */ + u8 country_code; /* Country Code */ u16 pa0b0; u16 pa0b1; u16 pa0b2; @@ -41,61 +33,15 @@ struct ssb_sprom_r1 { u8 gpio1; /* GPIO pin 1 */ u8 gpio2; /* GPIO pin 2 */ u8 gpio3; /* GPIO pin 3 */ - u16 maxpwr_a; /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */ - u16 maxpwr_bg; /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */ + u16 maxpwr_a; /* A-PHY Amplifier Max Power (in dBm Q5.2) */ + u16 maxpwr_bg; /* B/G-PHY Amplifier Max Power (in dBm Q5.2) */ u8 itssi_a; /* Idle TSSI Target for A-PHY */ u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */ u16 boardflags_lo; /* Boardflags (low 16 bits) */ u8 antenna_gain_a; /* A-PHY Antenna gain (in dBm Q5.2) */ u8 antenna_gain_bg; /* B/G-PHY Antenna gain (in dBm Q5.2) */ - u8 oem[8]; /* OEM string (rev 1 only) */ -}; - -struct ssb_sprom_r2 { - u16 boardflags_hi; /* Boardflags (high 16 bits) */ - u8 maxpwr_a_lo; /* A-PHY Max Power Low */ - u8 maxpwr_a_hi; /* A-PHY Max Power High */ - u16 pa1lob0; /* A-PHY PA Low Settings */ - u16 pa1lob1; /* A-PHY PA Low Settings */ - u16 pa1lob2; /* A-PHY PA Low Settings */ - u16 pa1hib0; /* A-PHY PA High Settings */ - u16 pa1hib1; /* A-PHY PA High Settings */ - u16 pa1hib2; /* A-PHY PA High Settings */ - u8 ofdm_pwr_off; /* OFDM Power Offset from CCK Level */ - u8 country_str[2]; /* Two char Country Code */ -}; -struct ssb_sprom_r3 { - u32 ofdmapo; /* A-PHY OFDM Mid Power Offset */ - u32 ofdmalpo; /* A-PHY OFDM Low Power Offset */ - u32 ofdmahpo; /* A-PHY OFDM High Power Offset */ - u8 gpioldc_on_cnt; /* GPIO LED Powersave Duty Cycle ON count */ - u8 gpioldc_off_cnt; /* GPIO LED Powersave Duty Cycle OFF count */ - u8 cckpo_1M:4; /* CCK Power Offset for Rate 1M */ - u8 cckpo_2M:4; /* CCK Power Offset for Rate 2M */ - u8 cckpo_55M:4; /* CCK Power Offset for Rate 5.5M */ - u8 cckpo_11M:4; /* CCK Power Offset for Rate 11M */ - u32 ofdmgpo; /* G-PHY OFDM Power Offset */ -}; - -struct ssb_sprom_r4 { - /* TODO */ -}; - -struct ssb_sprom { - u8 revision; - u8 crc; - /* The valid r# fields are selected by the "revision". - * Revision 3 and lower inherit from lower revisions. - */ - union { - struct { - struct ssb_sprom_r1 r1; - struct ssb_sprom_r2 r2; - struct ssb_sprom_r3 r3; - }; - struct ssb_sprom_r4 r4; - }; + /* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */ }; /* Information about the PCB the circuitry is soldered on. */ @@ -288,6 +234,7 @@ struct ssb_bus { /* ID information about the Chip. */ u16 chip_id; u16 chip_rev; + u16 sprom_size; /* number of words in sprom */ u8 chip_package; /* List of devices (cores) on the backplane. */ diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 47c7c71..30222e8 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -147,6 +147,10 @@ #define SSB_IDLOW_SSBREV 0xF0000000 /* Sonics Backplane Revision code */ #define SSB_IDLOW_SSBREV_22 0x00000000 /* <= 2.2 */ #define SSB_IDLOW_SSBREV_23 0x10000000 /* 2.3 */ +#define SSB_IDLOW_SSBREV_24 0x40000000 /* ?? Found in BCM4328 */ +#define SSB_IDLOW_SSBREV_25 0x50000000 /* ?? Not Found yet */ +#define SSB_IDLOW_SSBREV_26 0x60000000 /* ?? Found in some BCM4311/2 */ +#define SSB_IDLOW_SSBREV_27 0x70000000 /* ?? Found in some BCM4311/2 */ #define SSB_IDHIGH 0x0FFC /* SB Identification High */ #define SSB_IDHIGH_RCLO 0x0000000F /* Revision Code (low part) */ #define SSB_IDHIGH_CC 0x00008FF0 /* Core Code */ @@ -162,11 +166,16 @@ */ #define SSB_SPROMSIZE_WORDS 64 #define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16)) +#define SSB_SPROMSIZE_WORDS_R123 64 +#define SSB_SPROMSIZE_WORDS_R4 220 +#define SSB_SPROMSIZE_BYTES_R123 (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16)) +#define SSB_SPROMSIZE_BYTES_R4 (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16)) #define SSB_SPROM_BASE 0x1000 #define SSB_SPROM_REVISION 0x107E #define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */ #define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */ #define SSB_SPROM_REVISION_CRC_SHIFT 8 + /* SPROM Revision 1 */ #define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */ #define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */ @@ -215,7 +224,7 @@ #define SSB_SPROM1_AGAIN_A 0x00FF /* A-PHY */ #define SSB_SPROM1_AGAIN_BG 0xFF00 /* B-PHY and G-PHY */ #define SSB_SPROM1_AGAIN_BG_SHIFT 8 -#define SSB_SPROM1_OEM 0x1076 /* 8 bytes OEM string (rev 1 only) */ + /* SPROM Revision 2 (inherits from rev 1) */ #define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */ #define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */ @@ -232,7 +241,11 @@ #define SSB_SPROM2_OPO_VALUE 0x00FF #define SSB_SPROM2_OPO_UNUSED 0xFF00 #define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */ -/* SPROM Revision 3 (inherits from rev 2) */ + +/* SPROM Revision 3 (inherits most data from rev 2) */ +#define SSB_SPROM3_IL0MAC 0x104A /* 6 bytes MAC address for 802.11b/g */ +#define SSB_SPROM3_ET0MAC 0x1050 /* 6 bytes MAC address for Ethernet ?? */ +#define SSB_SPROM3_ET1MAC 0x1050 /* 6 bytes MAC address for 802.11a ?? */ #define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */ #define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */ #define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */ @@ -251,6 +264,48 @@ #define SSB_SPROM3_CCKPO_11M_SHIFT 12 #define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */ +/* SPROM Revision 4 entries with ?? in comment are unknown */ +#define SSB_SPROM4_IL0MAC 0x104C /* 6 byte MAC address for a/b/g/n */ +#define SSB_SPROM4_ET0MAC 0x1018 /* 6 bytes MAC address for Ethernet ?? */ +#define SSB_SPROM4_ET1MAC 0x1018 /* 6 bytes MAC address for 802.11a ?? */ +#define SSB_SPROM4_ETHPHY 0x105A /* Ethernet PHY settings ?? */ +#define SSB_SPROM4_ETHPHY_ET0A 0x001F /* MII Address for enet0 */ +#define SSB_SPROM4_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */ +#define SSB_SPROM4_ETHPHY_ET1A_SHIFT 5 +#define SSB_SPROM4_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */ +#define SSB_SPROM4_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */ +#define SSB_SPROM4_CCODE 0x1052 /* Country Code (2 bytes) */ +#define SSB_SPROM4_ANT_A 0x105D /* A Antennas */ +#define SSB_SPROM4_ANT_BG 0x105C /* B/G Antennas */ +#define SSB_SPROM4_BFLLO 0x1044 /* Boardflags (low 16 bits) */ +#define SSB_SPROM4_AGAIN 0x105E /* Antenna Gain (in dBm Q5.2) */ +#define SSB_SPROM4_AGAIN_0 0x00FF /* Antenna 0 */ +#define SSB_SPROM4_AGAIN_1 0xFF00 /* Antenna 1 */ +#define SSB_SPROM4_AGAIN_1_SHIFT 8 +#define SSB_SPROM4_BFLHI 0x1046 /* Board Flags Hi */ +#define SSB_SPROM4_MAXP_BG 0x1080 /* Max Power BG in path 1 */ +#define SSB_SPROM4_MAXP_BG_MASK 0x00FF /* Mask for Max Power BG */ +#define SSB_SPROM4_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ +#define SSB_SPROM4_ITSSI_BG_SHIFT 8 +#define SSB_SPROM4_MAXP_A 0x108A /* Max Power A in path 1 */ +#define SSB_SPROM4_MAXP_A_MASK 0x00FF /* Mask for Max Power A */ +#define SSB_SPROM4_ITSSI_A 0xFF00 /* Mask for path 1 itssi_a */ +#define SSB_SPROM4_ITSSI_A_SHIFT 8 +#define SSB_SPROM4_GPIOA 0x1056 /* Gen. Purpose IO # 0 and 1 */ +#define SSB_SPROM4_GPIOA_P0 0x00FF /* Pin 0 */ +#define SSB_SPROM4_GPIOA_P1 0xFF00 /* Pin 1 */ +#define SSB_SPROM4_GPIOA_P1_SHIFT 8 +#define SSB_SPROM4_GPIOB 0x1058 /* Gen. Purpose IO # 2 and 3 */ +#define SSB_SPROM4_GPIOB_P2 0x00FF /* Pin 2 */ +#define SSB_SPROM4_GPIOB_P3 0xFF00 /* Pin 3 */ +#define SSB_SPROM4_GPIOB_P3_SHIFT 8 +#define SSB_SPROM4_PA0B0 0x1082 /* The paXbY locations are */ +#define SSB_SPROM4_PA0B1 0x1084 /* only guesses */ +#define SSB_SPROM4_PA0B2 0x1086 +#define SSB_SPROM4_PA1B0 0x108E +#define SSB_SPROM4_PA1B1 0x1090 +#define SSB_SPROM4_PA1B2 0x1092 + /* Values for SSB_SPROM1_BINF_CCODE */ enum { SSB_SPROM1CCODE_WORLD = 0, diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c index d309e8f..623489a 100644 --- a/net/ieee80211/ieee80211_wx.c +++ b/net/ieee80211/ieee80211_wx.c @@ -709,7 +709,7 @@ int ieee80211_wx_get_encodeext(struct ieee80211_device *ieee, } else idx = ieee->tx_keyidx; - if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY && + if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && ext->alg != IW_ENCODE_ALG_WEP) if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) return -EINVAL;