Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6:
Staging: comedi: fix build on arches that don't want comedi drivers
Staging: comedi: pcmcia irq fixes
Staging: comedi: ni_pcimio: Added device id for pxi-6225.
Staging: comedi: ni_65xx.c: fix output inversion problem.
Staging: comedi: ni_65xx.c: fix insn_bits shift calculation.
Staging: comedi: s526: fixes for pulse generator
Staging: comedi: s526: Take account of arch's byte order.
Staging: comedi: s526: Get rid of global variable 'cmReg'.
Staging: comedi: s526: Fix number of channels on DIO subdevice
Staging: comedi: cb_pcidio: fix "section mismatch" error
Staging: comedi: jr3_pci: Initialize transf variable fully in jr3_pci_poll_subdevice().
Staging: comedi: Corrected type of a printk argument in resize_async_buffer().
Staging: p9auth: a few fixes
Staging: rtl8192e: Add #include <linux/vmalloc.h>
Staging: iio: Don't build on s390
Staging: winbond: implement prepare_multicast and fix API usage
Staging: w35und: Fix ->beacon_int breakage
Staging: remove cowloop driver
Staging: remove agnx driver
Staging: comedi: serial2002: fix include build issue

+148 -8248
-4
drivers/staging/Kconfig
··· 59 59 60 60 source "drivers/staging/poch/Kconfig" 61 61 62 - source "drivers/staging/agnx/Kconfig" 63 - 64 62 source "drivers/staging/otus/Kconfig" 65 63 66 64 source "drivers/staging/rt2860/Kconfig" ··· 126 128 source "drivers/staging/sep/Kconfig" 127 129 128 130 source "drivers/staging/iio/Kconfig" 129 - 130 - source "drivers/staging/cowloop/Kconfig" 131 131 132 132 endif # !STAGING_EXCLUDE_BUILD 133 133 endif # STAGING
-2
drivers/staging/Makefile
··· 12 12 obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 13 13 obj-$(CONFIG_ECHO) += echo/ 14 14 obj-$(CONFIG_POCH) += poch/ 15 - obj-$(CONFIG_AGNX) += agnx/ 16 15 obj-$(CONFIG_OTUS) += otus/ 17 16 obj-$(CONFIG_RT2860) += rt2860/ 18 17 obj-$(CONFIG_RT2870) += rt2870/ ··· 45 46 obj-$(CONFIG_RAR_REGISTER) += rar/ 46 47 obj-$(CONFIG_DX_SEP) += sep/ 47 48 obj-$(CONFIG_IIO) += iio/ 48 - obj-$(CONFIG_COWLOOP) += cowloop/
-5
drivers/staging/agnx/Kconfig
··· 1 - config AGNX 2 - tristate "Wireless Airgo AGNX support" 3 - depends on WLAN_80211 && MAC80211 4 - ---help--- 5 - This is an experimental driver for Airgo AGNX00 wireless chip.
-8
drivers/staging/agnx/Makefile
··· 1 - obj-$(CONFIG_AGNX) += agnx.o 2 - 3 - agnx-objs := rf.o \ 4 - pci.o \ 5 - xmit.o \ 6 - table.o \ 7 - sta.o \ 8 - phy.o
-22
drivers/staging/agnx/TODO
··· 1 - 2008 7/18 2 - 3 - The RX has can't receive OFDM packet correctly, 4 - Guess it need be do RX calibrate. 5 - 6 - 7 - before 2008 3/1 8 - 9 - 1: The RX get too much "CRC failed" pakets, it make the card work very unstable, 10 - 2: After running a while, the card will get infinity "RX Frame" and "Error" 11 - interrupt, not know the root reason so far, try to fix it 12 - 3: Using two tx queue txd and txm but not only txm. 13 - 4: Set the hdr correctly. 14 - 5: Try to do recalibrate correvtly 15 - 6: To support G mode in future 16 - 7: Fix the mac address can't be readed and set correctly in BE machine. 17 - 8: Fix include and exclude FCS in promisous mode and manage mode 18 - 9: Using sta_notify to notice sta change 19 - 10: Turn on frame reception at the end of start 20 - 11: Guess the card support HW_MULTICAST_FILTER 21 - 12: The tx process should be implment atomic? 22 - 13: Using mac80211 function to control the TX&RX LED.
-156
drivers/staging/agnx/agnx.h
··· 1 - #ifndef AGNX_H_ 2 - #define AGNX_H_ 3 - 4 - #include <linux/io.h> 5 - 6 - #include "xmit.h" 7 - 8 - #define PFX KBUILD_MODNAME ": " 9 - 10 - static inline u32 agnx_read32(void __iomem *mem_region, u32 offset) 11 - { 12 - return ioread32(mem_region + offset); 13 - } 14 - 15 - static inline void agnx_write32(void __iomem *mem_region, u32 offset, u32 val) 16 - { 17 - iowrite32(val, mem_region + offset); 18 - } 19 - 20 - /* static const struct ieee80211_rate agnx_rates_80211b[] = { */ 21 - /* { .rate = 10, */ 22 - /* .val = 0xa, */ 23 - /* .flags = IEEE80211_RATE_CCK }, */ 24 - /* { .rate = 20, */ 25 - /* .val = 0x14, */ 26 - /* .hw_value = -0x14, */ 27 - /* .flags = IEEE80211_RATE_CCK_2 }, */ 28 - /* { .rate = 55, */ 29 - /* .val = 0x37, */ 30 - /* .val2 = -0x37, */ 31 - /* .flags = IEEE80211_RATE_CCK_2 }, */ 32 - /* { .rate = 110, */ 33 - /* .val = 0x6e, */ 34 - /* .val2 = -0x6e, */ 35 - /* .flags = IEEE80211_RATE_CCK_2 } */ 36 - /* }; */ 37 - 38 - 39 - static const struct ieee80211_rate agnx_rates_80211g[] = { 40 - /* { .bitrate = 10, .hw_value = 1, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */ 41 - /* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */ 42 - /* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */ 43 - /* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */ 44 - { .bitrate = 10, .hw_value = 1, }, 45 - { .bitrate = 20, .hw_value = 2, }, 46 - { .bitrate = 55, .hw_value = 3, }, 47 - { .bitrate = 110, .hw_value = 4,}, 48 - 49 - { .bitrate = 60, .hw_value = 0xB, }, 50 - { .bitrate = 90, .hw_value = 0xF, }, 51 - { .bitrate = 120, .hw_value = 0xA }, 52 - { .bitrate = 180, .hw_value = 0xE, }, 53 - /* { .bitrate = 240, .hw_value = 0xd, }, */ 54 - { .bitrate = 360, .hw_value = 0xD, }, 55 - { .bitrate = 480, .hw_value = 0x8, }, 56 - { .bitrate = 540, .hw_value = 0xC, }, 57 - }; 58 - 59 - static const struct ieee80211_channel agnx_channels[] = { 60 - { .center_freq = 2412, .hw_value = 1, }, 61 - { .center_freq = 2417, .hw_value = 2, }, 62 - { .center_freq = 2422, .hw_value = 3, }, 63 - { .center_freq = 2427, .hw_value = 4, }, 64 - { .center_freq = 2432, .hw_value = 5, }, 65 - { .center_freq = 2437, .hw_value = 6, }, 66 - { .center_freq = 2442, .hw_value = 7, }, 67 - { .center_freq = 2447, .hw_value = 8, }, 68 - { .center_freq = 2452, .hw_value = 9, }, 69 - { .center_freq = 2457, .hw_value = 10, }, 70 - { .center_freq = 2462, .hw_value = 11, }, 71 - { .center_freq = 2467, .hw_value = 12, }, 72 - { .center_freq = 2472, .hw_value = 13, }, 73 - { .center_freq = 2484, .hw_value = 14, }, 74 - }; 75 - 76 - #define NUM_DRIVE_MODES 2 77 - /* Agnx operate mode */ 78 - enum { 79 - AGNX_MODE_80211A, 80 - AGNX_MODE_80211A_OOB, 81 - AGNX_MODE_80211A_MIMO, 82 - AGNX_MODE_80211B_SHORT, 83 - AGNX_MODE_80211B_LONG, 84 - AGNX_MODE_80211G, 85 - AGNX_MODE_80211G_OOB, 86 - AGNX_MODE_80211G_MIMO, 87 - }; 88 - 89 - enum { 90 - AGNX_UNINIT, 91 - AGNX_START, 92 - AGNX_STOP, 93 - }; 94 - 95 - struct agnx_priv { 96 - struct pci_dev *pdev; 97 - struct ieee80211_hw *hw; 98 - 99 - spinlock_t lock; 100 - struct mutex mutex; 101 - unsigned int init_status; 102 - 103 - void __iomem *ctl; /* pointer to base ram address */ 104 - void __iomem *data; /* pointer to mem region #2 */ 105 - 106 - struct agnx_ring rx; 107 - struct agnx_ring txm; 108 - struct agnx_ring txd; 109 - 110 - /* Need volatile? */ 111 - u32 irq_status; 112 - 113 - struct delayed_work periodic_work; /* Periodic tasks like recalibrate */ 114 - struct ieee80211_low_level_stats stats; 115 - 116 - /* unsigned int phymode; */ 117 - int mode; 118 - int channel; 119 - u8 bssid[ETH_ALEN]; 120 - 121 - u8 mac_addr[ETH_ALEN]; 122 - u8 revid; 123 - 124 - struct ieee80211_supported_band band; 125 - }; 126 - 127 - 128 - #define AGNX_CHAINS_MAX 6 129 - #define AGNX_PERIODIC_DELAY 60000 /* unit: ms */ 130 - #define LOCAL_STAID 0 /* the station entry for the card itself */ 131 - #define BSSID_STAID 1 /* the station entry for the bsssid AP */ 132 - #define spi_delay() udelay(40) 133 - #define eeprom_delay() udelay(40) 134 - #define routing_table_delay() udelay(50) 135 - 136 - /* PDU pool MEM region #2 */ 137 - #define AGNX_PDUPOOL 0x40000 /* PDU pool */ 138 - #define AGNX_PDUPOOL_SIZE 0x8000 /* PDU pool size*/ 139 - #define AGNX_PDU_TX_WQ 0x41000 /* PDU list TX workqueue */ 140 - #define AGNX_PDU_FREE 0x41800 /* Free Pool */ 141 - #define PDU_SIZE 0x80 /* Free Pool node size */ 142 - #define PDU_FREE_CNT 0xd0 /* Free pool node count */ 143 - 144 - 145 - /* RF stuffs */ 146 - extern void rf_chips_init(struct agnx_priv *priv); 147 - extern void spi_rc_write(void __iomem *mem_region, u32 chip_ids, u32 sw); 148 - extern void calibrate_oscillator(struct agnx_priv *priv); 149 - extern void do_calibration(struct agnx_priv *priv); 150 - extern void antenna_calibrate(struct agnx_priv *priv); 151 - extern void __antenna_calibrate(struct agnx_priv *priv); 152 - extern void print_offsets(struct agnx_priv *priv); 153 - extern int agnx_set_channel(struct agnx_priv *priv, unsigned int channel); 154 - 155 - 156 - #endif /* AGNX_H_ */
-416
drivers/staging/agnx/debug.h
··· 1 - #ifndef AGNX_DEBUG_H_ 2 - #define AGNX_DEBUG_H_ 3 - 4 - #include "agnx.h" 5 - #include "phy.h" 6 - #include "sta.h" 7 - #include "xmit.h" 8 - 9 - #define AGNX_TRACE printk(KERN_ERR PFX "function:%s line:%d\n", __func__, __LINE__) 10 - 11 - #define PRINTK_LE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", le16_to_cpu(var)) 12 - #define PRINTK_LE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", le32_to_cpu(var)) 13 - #define PRINTK_U8(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.2x\n", var) 14 - #define PRINTK_BE16(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.4x\n", be16_to_cpu(var)) 15 - #define PRINTK_BE32(prefix, var) printk(KERN_DEBUG PFX #prefix ": " #var " 0x%.8x\n", be32_to_cpu(var)) 16 - #define PRINTK_BITS(prefix, field) printk(KERN_DEBUG PFX #prefix ": " #field ": 0x%x\n", (reg & field) >> field##_SHIFT) 17 - 18 - static inline void agnx_bug(char *reason) 19 - { 20 - printk(KERN_ERR PFX "%s\n", reason); 21 - BUG(); 22 - } 23 - 24 - static inline void agnx_print_desc(struct agnx_desc *desc) 25 - { 26 - u32 reg = be32_to_cpu(desc->frag); 27 - 28 - PRINTK_BITS(DESC, PACKET_LEN); 29 - 30 - if (reg & FIRST_FRAG) { 31 - PRINTK_BITS(DESC, FIRST_PACKET_MASK); 32 - PRINTK_BITS(DESC, FIRST_RESERV2); 33 - PRINTK_BITS(DESC, FIRST_TKIP_ERROR); 34 - PRINTK_BITS(DESC, FIRST_TKIP_PACKET); 35 - PRINTK_BITS(DESC, FIRST_RESERV1); 36 - PRINTK_BITS(DESC, FIRST_FRAG_LEN); 37 - } else { 38 - PRINTK_BITS(DESC, SUB_RESERV2); 39 - PRINTK_BITS(DESC, SUB_TKIP_ERROR); 40 - PRINTK_BITS(DESC, SUB_TKIP_PACKET); 41 - PRINTK_BITS(DESC, SUB_RESERV1); 42 - PRINTK_BITS(DESC, SUB_FRAG_LEN); 43 - } 44 - 45 - PRINTK_BITS(DESC, FIRST_FRAG); 46 - PRINTK_BITS(DESC, LAST_FRAG); 47 - PRINTK_BITS(DESC, OWNER); 48 - } 49 - 50 - 51 - static inline void dump_ieee80211b_phy_hdr(__be32 _11b0, __be32 _11b1) 52 - { 53 - 54 - } 55 - 56 - static inline void agnx_print_hdr(struct agnx_hdr *hdr) 57 - { 58 - u32 reg; 59 - int i; 60 - 61 - reg = be32_to_cpu(hdr->reg0); 62 - PRINTK_BITS(HDR, RTS); 63 - PRINTK_BITS(HDR, MULTICAST); 64 - PRINTK_BITS(HDR, ACK); 65 - PRINTK_BITS(HDR, TM); 66 - PRINTK_BITS(HDR, RELAY); 67 - PRINTK_BITS(HDR, REVISED_FCS); 68 - PRINTK_BITS(HDR, NEXT_BUFFER_ADDR); 69 - 70 - reg = be32_to_cpu(hdr->reg1); 71 - PRINTK_BITS(HDR, MAC_HDR_LEN); 72 - PRINTK_BITS(HDR, DURATION_OVERIDE); 73 - PRINTK_BITS(HDR, PHY_HDR_OVERIDE); 74 - PRINTK_BITS(HDR, CRC_FAIL); 75 - PRINTK_BITS(HDR, SEQUENCE_NUMBER); 76 - PRINTK_BITS(HDR, BUFF_HEAD_ADDR); 77 - 78 - reg = be32_to_cpu(hdr->reg2); 79 - PRINTK_BITS(HDR, PDU_COUNT); 80 - PRINTK_BITS(HDR, WEP_KEY); 81 - PRINTK_BITS(HDR, USES_WEP_KEY); 82 - PRINTK_BITS(HDR, KEEP_ALIVE); 83 - PRINTK_BITS(HDR, BUFF_TAIL_ADDR); 84 - 85 - reg = be32_to_cpu(hdr->reg3); 86 - PRINTK_BITS(HDR, CTS_11G); 87 - PRINTK_BITS(HDR, RTS_11G); 88 - PRINTK_BITS(HDR, FRAG_SIZE); 89 - PRINTK_BITS(HDR, PAYLOAD_LEN); 90 - PRINTK_BITS(HDR, FRAG_NUM); 91 - 92 - reg = be32_to_cpu(hdr->reg4); 93 - PRINTK_BITS(HDR, RELAY_STAID); 94 - PRINTK_BITS(HDR, STATION_ID); 95 - PRINTK_BITS(HDR, WORKQUEUE_ID); 96 - 97 - reg = be32_to_cpu(hdr->reg5); 98 - /* printf the route flag */ 99 - PRINTK_BITS(HDR, ROUTE_HOST); 100 - PRINTK_BITS(HDR, ROUTE_CARD_CPU); 101 - PRINTK_BITS(HDR, ROUTE_ENCRYPTION); 102 - PRINTK_BITS(HDR, ROUTE_TX); 103 - PRINTK_BITS(HDR, ROUTE_RX1); 104 - PRINTK_BITS(HDR, ROUTE_RX2); 105 - PRINTK_BITS(HDR, ROUTE_COMPRESSION); 106 - 107 - PRINTK_BE32(HDR, hdr->_11g0); 108 - PRINTK_BE32(HDR, hdr->_11g1); 109 - PRINTK_BE32(HDR, hdr->_11b0); 110 - PRINTK_BE32(HDR, hdr->_11b1); 111 - 112 - dump_ieee80211b_phy_hdr(hdr->_11b0, hdr->_11b1); 113 - 114 - /* Fixme */ 115 - for (i = 0; i < ARRAY_SIZE(hdr->mac_hdr); i++) { 116 - if (i == 0) 117 - printk(KERN_DEBUG PFX "IEEE80211 HDR: "); 118 - printk("%.2x ", hdr->mac_hdr[i]); 119 - if (i + 1 == ARRAY_SIZE(hdr->mac_hdr)) 120 - printk("\n"); 121 - } 122 - 123 - PRINTK_BE16(HDR, hdr->rts_duration); 124 - PRINTK_BE16(HDR, hdr->last_duration); 125 - PRINTK_BE16(HDR, hdr->sec_last_duration); 126 - PRINTK_BE16(HDR, hdr->other_duration); 127 - PRINTK_BE16(HDR, hdr->tx_other_duration); 128 - PRINTK_BE16(HDR, hdr->last_11g_len); 129 - PRINTK_BE16(HDR, hdr->other_11g_len); 130 - PRINTK_BE16(HDR, hdr->last_11b_len); 131 - PRINTK_BE16(HDR, hdr->other_11b_len); 132 - 133 - /* FIXME */ 134 - reg = be16_to_cpu(hdr->reg6); 135 - PRINTK_BITS(HDR, MBF); 136 - PRINTK_BITS(HDR, RSVD4); 137 - 138 - PRINTK_BE16(HDR, hdr->rx_frag_stat); 139 - 140 - PRINTK_BE32(HDR, hdr->time_stamp); 141 - PRINTK_BE32(HDR, hdr->phy_stats_hi); 142 - PRINTK_BE32(HDR, hdr->phy_stats_lo); 143 - PRINTK_BE32(HDR, hdr->mic_key0); 144 - PRINTK_BE32(HDR, hdr->mic_key1); 145 - } /* agnx_print_hdr */ 146 - 147 - 148 - static inline void agnx_print_rx_hdr(struct agnx_hdr *hdr) 149 - { 150 - agnx_print_hdr(hdr); 151 - 152 - PRINTK_BE16(HDR, hdr->rx.rx_packet_duration); 153 - PRINTK_BE16(HDR, hdr->rx.replay_cnt); 154 - 155 - PRINTK_U8(HDR, hdr->rx_channel); 156 - } 157 - 158 - static inline void agnx_print_tx_hdr(struct agnx_hdr *hdr) 159 - { 160 - agnx_print_hdr(hdr); 161 - 162 - PRINTK_U8(HDR, hdr->tx.long_retry_limit); 163 - PRINTK_U8(HDR, hdr->tx.short_retry_limit); 164 - PRINTK_U8(HDR, hdr->tx.long_retry_cnt); 165 - PRINTK_U8(HDR, hdr->tx.short_retry_cnt); 166 - 167 - PRINTK_U8(HDR, hdr->rx_channel); 168 - } 169 - 170 - static inline void 171 - agnx_print_sta_power(struct agnx_priv *priv, unsigned int sta_idx) 172 - { 173 - struct agnx_sta_power power; 174 - u32 reg; 175 - 176 - get_sta_power(priv, &power, sta_idx); 177 - 178 - reg = le32_to_cpu(power.reg); 179 - PRINTK_BITS(STA_POWER, SIGNAL); 180 - PRINTK_BITS(STA_POWER, RATE); 181 - PRINTK_BITS(STA_POWER, TIFS); 182 - PRINTK_BITS(STA_POWER, EDCF); 183 - PRINTK_BITS(STA_POWER, CHANNEL_BOND); 184 - PRINTK_BITS(STA_POWER, PHY_MODE); 185 - PRINTK_BITS(STA_POWER, POWER_LEVEL); 186 - PRINTK_BITS(STA_POWER, NUM_TRANSMITTERS); 187 - } 188 - 189 - static inline void 190 - agnx_print_sta_tx_wq(struct agnx_priv *priv, unsigned int sta_idx, unsigned int wq_idx) 191 - { 192 - struct agnx_sta_tx_wq tx_wq; 193 - u32 reg; 194 - 195 - get_sta_tx_wq(priv, &tx_wq, sta_idx, wq_idx); 196 - 197 - reg = le32_to_cpu(tx_wq.reg0); 198 - PRINTK_BITS(STA_TX_WQ, TAIL_POINTER); 199 - PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_LOW); 200 - 201 - reg = le32_to_cpu(tx_wq.reg3); 202 - PRINTK_BITS(STA_TX_WQ, HEAD_POINTER_HIGH); 203 - PRINTK_BITS(STA_TX_WQ, ACK_POINTER_LOW); 204 - 205 - reg = le32_to_cpu(tx_wq.reg1); 206 - PRINTK_BITS(STA_TX_WQ, ACK_POINTER_HIGH); 207 - PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_TAIL_PACK_CNT); 208 - PRINTK_BITS(STA_TX_WQ, ACK_TIMOUT_TAIL_PACK_CNT); 209 - 210 - reg = le32_to_cpu(tx_wq.reg2); 211 - PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_BYTE_CNT); 212 - PRINTK_BITS(STA_TX_WQ, HEAD_TIMOUT_WIN_LIM_FRAG_CNT); 213 - PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_ACK_TYPE); 214 - PRINTK_BITS(STA_TX_WQ, WORK_QUEUE_VALID); 215 - } 216 - 217 - static inline void agnx_print_sta_traffic(struct agnx_sta_traffic *traffic) 218 - { 219 - u32 reg; 220 - 221 - reg = le32_to_cpu(traffic->reg0); 222 - PRINTK_BITS(STA_TRAFFIC, ACK_TIMOUT_CNT); 223 - PRINTK_BITS(STA_TRAFFIC, TRAFFIC_ACK_TYPE); 224 - PRINTK_BITS(STA_TRAFFIC, NEW_PACKET); 225 - PRINTK_BITS(STA_TRAFFIC, TRAFFIC_VALID); 226 - PRINTK_BITS(STA_TRAFFIC, RX_HDR_DESC_POINTER); 227 - 228 - reg = le32_to_cpu(traffic->reg1); 229 - PRINTK_BITS(STA_TRAFFIC, RX_PACKET_TIMESTAMP); 230 - PRINTK_BITS(STA_TRAFFIC, TRAFFIC_RESERVED); 231 - PRINTK_BITS(STA_TRAFFIC, SV); 232 - PRINTK_BITS(STA_TRAFFIC, RX_SEQUENCE_NUM); 233 - 234 - PRINTK_LE32(STA_TRAFFIC, traffic->tx_replay_cnt_low); 235 - 236 - PRINTK_LE16(STA_TRAFFIC, traffic->tx_replay_cnt_high); 237 - PRINTK_LE16(STA_TRAFFIC, traffic->rx_replay_cnt_high); 238 - 239 - PRINTK_LE32(STA_TRAFFIC, traffic->rx_replay_cnt_low); 240 - } 241 - 242 - static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx) 243 - { 244 - struct agnx_sta station; 245 - struct agnx_sta *sta = &station; 246 - u32 reg; 247 - unsigned int i; 248 - 249 - get_sta(priv, sta, sta_idx); 250 - 251 - for (i = 0; i < 4; i++) 252 - PRINTK_LE32(STA, sta->tx_session_keys[i]); 253 - for (i = 0; i < 4; i++) 254 - PRINTK_LE32(STA, sta->rx_session_keys[i]); 255 - 256 - reg = le32_to_cpu(sta->reg); 257 - PRINTK_BITS(STA, ID_1); 258 - PRINTK_BITS(STA, ID_0); 259 - PRINTK_BITS(STA, ENABLE_CONCATENATION); 260 - PRINTK_BITS(STA, ENABLE_DECOMPRESSION); 261 - PRINTK_BITS(STA, STA_RESERVED); 262 - PRINTK_BITS(STA, EAP); 263 - PRINTK_BITS(STA, ED_NULL); 264 - PRINTK_BITS(STA, ENCRYPTION_POLICY); 265 - PRINTK_BITS(STA, DEFINED_KEY_ID); 266 - PRINTK_BITS(STA, FIXED_KEY); 267 - PRINTK_BITS(STA, KEY_VALID); 268 - PRINTK_BITS(STA, STATION_VALID); 269 - 270 - PRINTK_LE32(STA, sta->tx_aes_blks_unicast); 271 - PRINTK_LE32(STA, sta->rx_aes_blks_unicast); 272 - 273 - PRINTK_LE16(STA, sta->aes_format_err_unicast_cnt); 274 - PRINTK_LE16(STA, sta->aes_replay_unicast); 275 - 276 - PRINTK_LE16(STA, sta->aes_decrypt_err_unicast); 277 - PRINTK_LE16(STA, sta->aes_decrypt_err_default); 278 - 279 - PRINTK_LE16(STA, sta->single_retry_packets); 280 - PRINTK_LE16(STA, sta->failed_tx_packets); 281 - 282 - PRINTK_LE16(STA, sta->muti_retry_packets); 283 - PRINTK_LE16(STA, sta->ack_timeouts); 284 - 285 - PRINTK_LE16(STA, sta->frag_tx_cnt); 286 - PRINTK_LE16(STA, sta->rts_brq_sent); 287 - 288 - PRINTK_LE16(STA, sta->tx_packets); 289 - PRINTK_LE16(STA, sta->cts_back_timeout); 290 - 291 - PRINTK_LE32(STA, sta->phy_stats_high); 292 - PRINTK_LE32(STA, sta->phy_stats_low); 293 - 294 - /* for (i = 0; i < 8; i++) */ 295 - agnx_print_sta_traffic(sta->traffic + 0); 296 - 297 - PRINTK_LE16(STA, sta->traffic_class0_frag_success); 298 - PRINTK_LE16(STA, sta->traffic_class1_frag_success); 299 - PRINTK_LE16(STA, sta->traffic_class2_frag_success); 300 - PRINTK_LE16(STA, sta->traffic_class3_frag_success); 301 - PRINTK_LE16(STA, sta->traffic_class4_frag_success); 302 - PRINTK_LE16(STA, sta->traffic_class5_frag_success); 303 - PRINTK_LE16(STA, sta->traffic_class6_frag_success); 304 - PRINTK_LE16(STA, sta->traffic_class7_frag_success); 305 - 306 - PRINTK_LE16(STA, sta->num_frag_non_prime_rates); 307 - PRINTK_LE16(STA, sta->ack_timeout_non_prime_rates); 308 - } 309 - 310 - 311 - static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag) 312 - { 313 - u16 fctl; 314 - int hdrlen; 315 - 316 - fctl = le16_to_cpu(hdr->frame_control); 317 - switch (fctl & IEEE80211_FCTL_FTYPE) { 318 - case IEEE80211_FTYPE_DATA: 319 - printk(PFX "%s DATA ", tag); 320 - break; 321 - case IEEE80211_FTYPE_CTL: 322 - printk(PFX "%s CTL ", tag); 323 - break; 324 - case IEEE80211_FTYPE_MGMT: 325 - printk(PFX "%s MGMT ", tag); 326 - switch (fctl & IEEE80211_FCTL_STYPE) { 327 - case IEEE80211_STYPE_ASSOC_REQ: 328 - printk("SubType: ASSOC_REQ "); 329 - break; 330 - case IEEE80211_STYPE_ASSOC_RESP: 331 - printk("SubType: ASSOC_RESP "); 332 - break; 333 - case IEEE80211_STYPE_REASSOC_REQ: 334 - printk("SubType: REASSOC_REQ "); 335 - break; 336 - case IEEE80211_STYPE_REASSOC_RESP: 337 - printk("SubType: REASSOC_RESP "); 338 - break; 339 - case IEEE80211_STYPE_PROBE_REQ: 340 - printk("SubType: PROBE_REQ "); 341 - break; 342 - case IEEE80211_STYPE_PROBE_RESP: 343 - printk("SubType: PROBE_RESP "); 344 - break; 345 - case IEEE80211_STYPE_BEACON: 346 - printk("SubType: BEACON "); 347 - break; 348 - case IEEE80211_STYPE_ATIM: 349 - printk("SubType: ATIM "); 350 - break; 351 - case IEEE80211_STYPE_DISASSOC: 352 - printk("SubType: DISASSOC "); 353 - break; 354 - case IEEE80211_STYPE_AUTH: 355 - printk("SubType: AUTH "); 356 - break; 357 - case IEEE80211_STYPE_DEAUTH: 358 - printk("SubType: DEAUTH "); 359 - break; 360 - case IEEE80211_STYPE_ACTION: 361 - printk("SubType: ACTION "); 362 - break; 363 - default: 364 - printk("SubType: Unknow\n"); 365 - } 366 - break; 367 - default: 368 - printk(PFX "%s Packet type: Unknow\n", tag); 369 - } 370 - 371 - hdrlen = ieee80211_hdrlen(fctl); 372 - 373 - if (hdrlen >= 4) 374 - printk("FC=0x%04x DUR=0x%04x", 375 - fctl, le16_to_cpu(hdr->duration_id)); 376 - if (hdrlen >= 10) 377 - printk(" A1=%pM", hdr->addr1); 378 - if (hdrlen >= 16) 379 - printk(" A2=%pM", hdr->addr2); 380 - if (hdrlen >= 24) 381 - printk(" A3=%pM", hdr->addr3); 382 - if (hdrlen >= 30) 383 - printk(" A4=%pM", hdr->addr4); 384 - printk("\n"); 385 - } 386 - 387 - static inline void dump_txm_registers(struct agnx_priv *priv) 388 - { 389 - void __iomem *ctl = priv->ctl; 390 - int i; 391 - for (i = 0; i <= 0x1e8; i += 4) 392 - printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i)); 393 - } 394 - static inline void dump_rxm_registers(struct agnx_priv *priv) 395 - { 396 - void __iomem *ctl = priv->ctl; 397 - int i; 398 - for (i = 0; i <= 0x108; i += 4) 399 - printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i)); 400 - } 401 - static inline void dump_bm_registers(struct agnx_priv *priv) 402 - { 403 - void __iomem *ctl = priv->ctl; 404 - int i; 405 - for (i = 0; i <= 0x90; i += 4) 406 - printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i)); 407 - } 408 - static inline void dump_cir_registers(struct agnx_priv *priv) 409 - { 410 - void __iomem *ctl = priv->ctl; 411 - int i; 412 - for (i = 0; i <= 0xb8; i += 4) 413 - printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i)); 414 - } 415 - 416 - #endif /* AGNX_DEBUG_H_ */
-635
drivers/staging/agnx/pci.c
··· 1 - /** 2 - * Airgo MIMO wireless driver 3 - * 4 - * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com> 5 - 6 - * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer 7 - * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin 8 - 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation. 12 - */ 13 - 14 - #include <linux/init.h> 15 - #include <linux/etherdevice.h> 16 - #include <linux/pci.h> 17 - #include <linux/delay.h> 18 - 19 - #include "agnx.h" 20 - #include "debug.h" 21 - #include "xmit.h" 22 - #include "phy.h" 23 - 24 - MODULE_AUTHOR("Li YanBo <dreamfly281@gmail.com>"); 25 - MODULE_DESCRIPTION("Airgo MIMO PCI wireless driver"); 26 - MODULE_LICENSE("GPL"); 27 - 28 - static struct pci_device_id agnx_pci_id_tbl[] __devinitdata = { 29 - { PCI_DEVICE(0x17cb, 0x0001) }, /* Beklin F5d8010, Netgear WGM511 etc */ 30 - { PCI_DEVICE(0x17cb, 0x0002) }, /* Netgear Wpnt511 */ 31 - { 0 } 32 - }; 33 - 34 - MODULE_DEVICE_TABLE(pci, agnx_pci_id_tbl); 35 - 36 - 37 - static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason) 38 - { 39 - void __iomem *ctl = priv->ctl; 40 - u32 reg; 41 - 42 - if (*reason & AGNX_STAT_RX) { 43 - /* Mark complete RX */ 44 - reg = ioread32(ctl + AGNX_CIR_RXCTL); 45 - reg |= 0x4; 46 - iowrite32(reg, ctl + AGNX_CIR_RXCTL); 47 - /* disable Rx interrupt */ 48 - } 49 - if (*reason & AGNX_STAT_TX) { 50 - reg = ioread32(ctl + AGNX_CIR_TXDCTL); 51 - if (reg & 0x4) { 52 - iowrite32(reg, ctl + AGNX_CIR_TXDCTL); 53 - *reason |= AGNX_STAT_TXD; 54 - } 55 - reg = ioread32(ctl + AGNX_CIR_TXMCTL); 56 - if (reg & 0x4) { 57 - iowrite32(reg, ctl + AGNX_CIR_TXMCTL); 58 - *reason |= AGNX_STAT_TXM; 59 - } 60 - } 61 - #if 0 62 - if (*reason & AGNX_STAT_X) { 63 - reg = ioread32(ctl + AGNX_INT_STAT); 64 - iowrite32(reg, ctl + AGNX_INT_STAT); 65 - /* FIXME reinit interrupt mask */ 66 - reg = 0xc390bf9 & ~IRQ_TX_BEACON; 67 - reg &= ~IRQ_TX_DISABLE; 68 - iowrite32(reg, ctl + AGNX_INT_MASK); 69 - iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); 70 - } 71 - #endif 72 - } /* agnx_interrupt_ack */ 73 - 74 - static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id) 75 - { 76 - struct ieee80211_hw *dev = dev_id; 77 - struct agnx_priv *priv = dev->priv; 78 - void __iomem *ctl = priv->ctl; 79 - irqreturn_t ret = IRQ_NONE; 80 - u32 irq_reason; 81 - 82 - spin_lock(&priv->lock); 83 - 84 - /* printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */ 85 - 86 - if (priv->init_status != AGNX_START) 87 - goto out; 88 - 89 - /* FiXME Here has no lock, Is this will lead to race? */ 90 - irq_reason = ioread32(ctl + AGNX_CIR_BLKCTL); 91 - if (!(irq_reason & 0x7)) 92 - goto out; 93 - 94 - ret = IRQ_HANDLED; 95 - priv->irq_status = ioread32(ctl + AGNX_INT_STAT); 96 - 97 - /* printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */ 98 - /* Make sure the txm and txd flags don't conflict with other unknown 99 - interrupt flag, maybe is not necessary */ 100 - irq_reason &= 0xF; 101 - 102 - disable_rx_interrupt(priv); 103 - /* TODO Make sure the card finished initialized */ 104 - agnx_interrupt_ack(priv, &irq_reason); 105 - 106 - if (irq_reason & AGNX_STAT_RX) 107 - handle_rx_irq(priv); 108 - if (irq_reason & AGNX_STAT_TXD) 109 - handle_txd_irq(priv); 110 - if (irq_reason & AGNX_STAT_TXM) 111 - handle_txm_irq(priv); 112 - if (irq_reason & AGNX_STAT_X) 113 - handle_other_irq(priv); 114 - 115 - enable_rx_interrupt(priv); 116 - out: 117 - spin_unlock(&priv->lock); 118 - return ret; 119 - } /* agnx_interrupt_handler */ 120 - 121 - 122 - /* FIXME */ 123 - static int agnx_tx(struct ieee80211_hw *dev, struct sk_buff *skb) 124 - { 125 - AGNX_TRACE; 126 - return _agnx_tx(dev->priv, skb); 127 - } /* agnx_tx */ 128 - 129 - 130 - static int agnx_get_mac_address(struct agnx_priv *priv) 131 - { 132 - void __iomem *ctl = priv->ctl; 133 - u32 reg; 134 - AGNX_TRACE; 135 - 136 - /* Attention! directly read the MAC or other date from EEPROM will 137 - lead to cardbus(WGM511) lock up when write to PM PLL register */ 138 - reg = agnx_read32(ctl, 0x3544); 139 - udelay(40); 140 - reg = agnx_read32(ctl, 0x354c); 141 - udelay(50); 142 - /* Get the mac address */ 143 - reg = agnx_read32(ctl, 0x3544); 144 - udelay(40); 145 - 146 - /* HACK */ 147 - reg = cpu_to_le32(reg); 148 - priv->mac_addr[0] = ((u8 *)&reg)[2]; 149 - priv->mac_addr[1] = ((u8 *)&reg)[3]; 150 - reg = agnx_read32(ctl, 0x3548); 151 - udelay(50); 152 - *((u32 *)(priv->mac_addr + 2)) = cpu_to_le32(reg); 153 - 154 - if (!is_valid_ether_addr(priv->mac_addr)) { 155 - printk(KERN_WARNING PFX "read mac %pM\n", priv->mac_addr); 156 - printk(KERN_WARNING PFX "Invalid hwaddr! Using random hwaddr\n"); 157 - random_ether_addr(priv->mac_addr); 158 - } 159 - 160 - return 0; 161 - } /* agnx_get_mac_address */ 162 - 163 - static int agnx_alloc_rings(struct agnx_priv *priv) 164 - { 165 - unsigned int len; 166 - AGNX_TRACE; 167 - 168 - /* Allocate RX/TXM/TXD rings info */ 169 - priv->rx.size = AGNX_RX_RING_SIZE; 170 - priv->txm.size = AGNX_TXM_RING_SIZE; 171 - priv->txd.size = AGNX_TXD_RING_SIZE; 172 - 173 - len = priv->rx.size + priv->txm.size + priv->txd.size; 174 - 175 - /* priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */ 176 - priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC); 177 - if (!priv->rx.info) 178 - return -ENOMEM; 179 - priv->txm.info = priv->rx.info + priv->rx.size; 180 - priv->txd.info = priv->txm.info + priv->txm.size; 181 - 182 - /* Allocate RX/TXM/TXD descriptors */ 183 - priv->rx.desc = pci_alloc_consistent(priv->pdev, sizeof(struct agnx_desc) * len, 184 - &priv->rx.dma); 185 - if (!priv->rx.desc) { 186 - kfree(priv->rx.info); 187 - return -ENOMEM; 188 - } 189 - 190 - priv->txm.desc = priv->rx.desc + priv->rx.size; 191 - priv->txm.dma = priv->rx.dma + sizeof(struct agnx_desc) * priv->rx.size; 192 - priv->txd.desc = priv->txm.desc + priv->txm.size; 193 - priv->txd.dma = priv->txm.dma + sizeof(struct agnx_desc) * priv->txm.size; 194 - 195 - return 0; 196 - } /* agnx_alloc_rings */ 197 - 198 - static void rings_free(struct agnx_priv *priv) 199 - { 200 - unsigned int len = priv->rx.size + priv->txm.size + priv->txd.size; 201 - unsigned long flags; 202 - AGNX_TRACE; 203 - 204 - spin_lock_irqsave(&priv->lock, flags); 205 - kfree(priv->rx.info); 206 - pci_free_consistent(priv->pdev, sizeof(struct agnx_desc) * len, 207 - priv->rx.desc, priv->rx.dma); 208 - spin_unlock_irqrestore(&priv->lock, flags); 209 - } 210 - 211 - #if 0 212 - static void agnx_periodic_work_handler(struct work_struct *work) 213 - { 214 - struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work); 215 - /* unsigned long flags; */ 216 - unsigned long delay; 217 - 218 - /* fixme: using mutex?? */ 219 - /* spin_lock_irqsave(&priv->lock, flags); */ 220 - 221 - /* TODO Recalibrate*/ 222 - /* calibrate_oscillator(priv); */ 223 - /* antenna_calibrate(priv); */ 224 - /* agnx_send_packet(priv, 997); */ 225 - /* FIXME */ 226 - /* if (debug == 3) */ 227 - /* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */ 228 - /* else */ 229 - delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); 230 - /* delay = round_jiffies(HZ * 15); */ 231 - 232 - queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay); 233 - 234 - /* spin_unlock_irqrestore(&priv->lock, flags); */ 235 - } 236 - #endif 237 - 238 - static int agnx_start(struct ieee80211_hw *dev) 239 - { 240 - struct agnx_priv *priv = dev->priv; 241 - /* unsigned long delay; */ 242 - int err = 0; 243 - AGNX_TRACE; 244 - 245 - err = agnx_alloc_rings(priv); 246 - if (err) { 247 - printk(KERN_ERR PFX "Can't alloc RX/TXM/TXD rings\n"); 248 - goto out; 249 - } 250 - err = request_irq(priv->pdev->irq, &agnx_interrupt_handler, 251 - IRQF_SHARED, "agnx_pci", dev); 252 - if (err) { 253 - printk(KERN_ERR PFX "Failed to register IRQ handler\n"); 254 - rings_free(priv); 255 - goto out; 256 - } 257 - 258 - /* mdelay(500); */ 259 - 260 - might_sleep(); 261 - agnx_hw_init(priv); 262 - 263 - /* mdelay(500); */ 264 - might_sleep(); 265 - 266 - priv->init_status = AGNX_START; 267 - /* INIT_DELAYED_WORK(&priv->periodic_work, agnx_periodic_work_handler); */ 268 - /* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */ 269 - /* queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay); */ 270 - out: 271 - return err; 272 - } /* agnx_start */ 273 - 274 - static void agnx_stop(struct ieee80211_hw *dev) 275 - { 276 - struct agnx_priv *priv = dev->priv; 277 - AGNX_TRACE; 278 - 279 - priv->init_status = AGNX_STOP; 280 - /* make sure hardware will not generate irq */ 281 - agnx_hw_reset(priv); 282 - free_irq(priv->pdev->irq, dev); 283 - /* flush_workqueue(priv->hw->workqueue); */ 284 - /* cancel_delayed_work_sync(&priv->periodic_work); */ 285 - unfill_rings(priv); 286 - rings_free(priv); 287 - } 288 - 289 - static int agnx_config(struct ieee80211_hw *dev, u32 changed) 290 - { 291 - struct agnx_priv *priv = dev->priv; 292 - struct ieee80211_conf *conf = &dev->conf; 293 - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); 294 - AGNX_TRACE; 295 - 296 - spin_lock(&priv->lock); 297 - /* FIXME need priv lock? */ 298 - if (channel != priv->channel) { 299 - priv->channel = channel; 300 - agnx_set_channel(priv, priv->channel); 301 - } 302 - 303 - spin_unlock(&priv->lock); 304 - return 0; 305 - } 306 - 307 - static void agnx_bss_info_changed(struct ieee80211_hw *dev, 308 - struct ieee80211_vif *vif, 309 - struct ieee80211_bss_conf *conf, 310 - u32 changed) 311 - { 312 - struct agnx_priv *priv = dev->priv; 313 - void __iomem *ctl = priv->ctl; 314 - AGNX_TRACE; 315 - 316 - if (!(changed & BSS_CHANGED_BSSID)) 317 - return; 318 - 319 - spin_lock(&priv->lock); 320 - 321 - if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) { 322 - agnx_set_bssid(priv, conf->bssid); 323 - memcpy(priv->bssid, conf->bssid, ETH_ALEN); 324 - hash_write(priv, conf->bssid, BSSID_STAID); 325 - sta_init(priv, BSSID_STAID); 326 - /* FIXME needed? */ 327 - sta_power_init(priv, BSSID_STAID); 328 - agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1); 329 - } 330 - spin_unlock(&priv->lock); 331 - } /* agnx_bss_info_changed */ 332 - 333 - 334 - static void agnx_configure_filter(struct ieee80211_hw *dev, 335 - unsigned int changed_flags, 336 - unsigned int *total_flags, 337 - int mc_count, struct dev_mc_list *mclist) 338 - { 339 - unsigned int new_flags = 0; 340 - 341 - *total_flags = new_flags; 342 - /* TODO */ 343 - } 344 - 345 - static int agnx_add_interface(struct ieee80211_hw *dev, 346 - struct ieee80211_if_init_conf *conf) 347 - { 348 - struct agnx_priv *priv = dev->priv; 349 - AGNX_TRACE; 350 - 351 - spin_lock(&priv->lock); 352 - /* FIXME */ 353 - if (priv->mode != NL80211_IFTYPE_MONITOR) 354 - return -EOPNOTSUPP; 355 - 356 - switch (conf->type) { 357 - case NL80211_IFTYPE_STATION: 358 - priv->mode = conf->type; 359 - break; 360 - default: 361 - return -EOPNOTSUPP; 362 - } 363 - 364 - spin_unlock(&priv->lock); 365 - 366 - return 0; 367 - } 368 - 369 - static void agnx_remove_interface(struct ieee80211_hw *dev, 370 - struct ieee80211_if_init_conf *conf) 371 - { 372 - struct agnx_priv *priv = dev->priv; 373 - AGNX_TRACE; 374 - 375 - /* TODO */ 376 - priv->mode = NL80211_IFTYPE_MONITOR; 377 - } 378 - 379 - static int agnx_get_stats(struct ieee80211_hw *dev, 380 - struct ieee80211_low_level_stats *stats) 381 - { 382 - struct agnx_priv *priv = dev->priv; 383 - AGNX_TRACE; 384 - spin_lock(&priv->lock); 385 - /* TODO !! */ 386 - memcpy(stats, &priv->stats, sizeof(*stats)); 387 - spin_unlock(&priv->lock); 388 - 389 - return 0; 390 - } 391 - 392 - static u64 agnx_get_tsft(struct ieee80211_hw *dev) 393 - { 394 - void __iomem *ctl = ((struct agnx_priv *)dev->priv)->ctl; 395 - u32 tsftl; 396 - u64 tsft; 397 - AGNX_TRACE; 398 - 399 - /* FIXME */ 400 - tsftl = ioread32(ctl + AGNX_TXM_TIMESTAMPLO); 401 - tsft = ioread32(ctl + AGNX_TXM_TIMESTAMPHI); 402 - tsft <<= 32; 403 - tsft |= tsftl; 404 - 405 - return tsft; 406 - } 407 - 408 - static int agnx_get_tx_stats(struct ieee80211_hw *dev, 409 - struct ieee80211_tx_queue_stats *stats) 410 - { 411 - struct agnx_priv *priv = dev->priv; 412 - AGNX_TRACE; 413 - 414 - /* FIXME now we just using txd queue, but should using txm queue too */ 415 - stats[0].len = (priv->txd.idx - priv->txd.idx_sent) / 2; 416 - stats[0].limit = priv->txd.size - 2; 417 - stats[0].count = priv->txd.idx / 2; 418 - 419 - return 0; 420 - } 421 - 422 - static struct ieee80211_ops agnx_ops = { 423 - .tx = agnx_tx, 424 - .start = agnx_start, 425 - .stop = agnx_stop, 426 - .add_interface = agnx_add_interface, 427 - .remove_interface = agnx_remove_interface, 428 - .config = agnx_config, 429 - .bss_info_changed = agnx_bss_info_changed, 430 - .configure_filter = agnx_configure_filter, 431 - .get_stats = agnx_get_stats, 432 - .get_tx_stats = agnx_get_tx_stats, 433 - .get_tsf = agnx_get_tsft 434 - }; 435 - 436 - static void __devexit agnx_pci_remove(struct pci_dev *pdev) 437 - { 438 - struct ieee80211_hw *dev = pci_get_drvdata(pdev); 439 - struct agnx_priv *priv; 440 - AGNX_TRACE; 441 - 442 - if (!dev) 443 - return; 444 - priv = dev->priv; 445 - ieee80211_unregister_hw(dev); 446 - pci_iounmap(pdev, priv->ctl); 447 - pci_iounmap(pdev, priv->data); 448 - pci_release_regions(pdev); 449 - pci_disable_device(pdev); 450 - 451 - ieee80211_free_hw(dev); 452 - } 453 - 454 - static int __devinit agnx_pci_probe(struct pci_dev *pdev, 455 - const struct pci_device_id *id) 456 - { 457 - struct ieee80211_hw *dev; 458 - struct agnx_priv *priv; 459 - int err; 460 - 461 - err = pci_enable_device(pdev); 462 - if (err) { 463 - dev_err(&pdev->dev, "can't enable pci device\n"); 464 - return err; 465 - } 466 - 467 - err = pci_request_regions(pdev, "agnx-pci"); 468 - if (err) { 469 - dev_err(&pdev->dev, "can't reserve PCI resources\n"); 470 - return err; 471 - } 472 - 473 - if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) || 474 - pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { 475 - dev_err(&pdev->dev, "no suitable DMA available\n"); 476 - err = -EIO; 477 - goto err_free_reg; 478 - } 479 - 480 - pci_set_master(pdev); 481 - 482 - dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops); 483 - if (!dev) { 484 - dev_err(&pdev->dev, "ieee80211 alloc failed\n"); 485 - err = -ENOMEM; 486 - goto err_free_reg; 487 - } 488 - priv = dev->priv; 489 - memset(priv, 0, sizeof(*priv)); 490 - priv->mode = NL80211_IFTYPE_MONITOR; 491 - priv->pdev = pdev; 492 - priv->hw = dev; 493 - spin_lock_init(&priv->lock); 494 - priv->init_status = AGNX_UNINIT; 495 - 496 - priv->ctl = pci_iomap(pdev, 0, 0); 497 - /* dev_dbg(&pdev->dev, "MEM1 mapped address is 0x%p\n", priv->ctl); */ 498 - if (!priv->ctl) { 499 - dev_err(&pdev->dev, "can't map device memory\n"); 500 - err = -ENOMEM; 501 - goto err_free_dev; 502 - } 503 - priv->data = pci_iomap(pdev, 1, 0); 504 - if (!priv->data) { 505 - dev_err(&pdev->dev, "can't map device memory\n"); 506 - err = -ENOMEM; 507 - goto err_iounmap2; 508 - } 509 - 510 - pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid); 511 - 512 - priv->band.channels = (struct ieee80211_channel *)agnx_channels; 513 - priv->band.n_channels = ARRAY_SIZE(agnx_channels); 514 - priv->band.bitrates = (struct ieee80211_rate *)agnx_rates_80211g; 515 - priv->band.n_bitrates = ARRAY_SIZE(agnx_rates_80211g); 516 - 517 - /* Init ieee802.11 dev */ 518 - SET_IEEE80211_DEV(dev, &pdev->dev); 519 - pci_set_drvdata(pdev, dev); 520 - dev->extra_tx_headroom = sizeof(struct agnx_hdr); 521 - 522 - /* FIXME It only include FCS in promious mode but not manage mode */ 523 - /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS; */ 524 - dev->channel_change_time = 5000; 525 - dev->max_signal = 100; 526 - /* FIXME */ 527 - dev->queues = 1; 528 - 529 - agnx_get_mac_address(priv); 530 - 531 - SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr); 532 - 533 - /* /\* FIXME *\/ */ 534 - /* for (i = 1; i < NUM_DRIVE_MODES; i++) { */ 535 - /* err = ieee80211_register_hwmode(dev, &priv->modes[i]); */ 536 - /* if (err) { */ 537 - /* printk(KERN_ERR PFX "Can't register hwmode\n"); */ 538 - /* goto err_iounmap; */ 539 - /* } */ 540 - /* } */ 541 - 542 - priv->channel = 1; 543 - dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 544 - 545 - err = ieee80211_register_hw(dev); 546 - if (err) { 547 - dev_err(&pdev->dev, "can't register hardware\n"); 548 - goto err_iounmap; 549 - } 550 - 551 - agnx_hw_reset(priv); 552 - 553 - dev_info(&pdev->dev, "%s: hwaddr %pM, Rev 0x%02x\n", 554 - wiphy_name(dev->wiphy), 555 - dev->wiphy->perm_addr, priv->revid); 556 - return 0; 557 - 558 - err_iounmap: 559 - pci_iounmap(pdev, priv->data); 560 - 561 - err_iounmap2: 562 - pci_iounmap(pdev, priv->ctl); 563 - 564 - err_free_dev: 565 - pci_set_drvdata(pdev, NULL); 566 - ieee80211_free_hw(dev); 567 - 568 - err_free_reg: 569 - pci_release_regions(pdev); 570 - 571 - pci_disable_device(pdev); 572 - return err; 573 - } /* agnx_pci_probe*/ 574 - 575 - #ifdef CONFIG_PM 576 - 577 - static int agnx_pci_suspend(struct pci_dev *pdev, pm_message_t state) 578 - { 579 - struct ieee80211_hw *dev = pci_get_drvdata(pdev); 580 - AGNX_TRACE; 581 - 582 - ieee80211_stop_queues(dev); 583 - agnx_stop(dev); 584 - 585 - pci_save_state(pdev); 586 - pci_set_power_state(pdev, pci_choose_state(pdev, state)); 587 - return 0; 588 - } 589 - 590 - static int agnx_pci_resume(struct pci_dev *pdev) 591 - { 592 - struct ieee80211_hw *dev = pci_get_drvdata(pdev); 593 - AGNX_TRACE; 594 - 595 - pci_set_power_state(pdev, PCI_D0); 596 - pci_restore_state(pdev); 597 - 598 - agnx_start(dev); 599 - ieee80211_wake_queues(dev); 600 - 601 - return 0; 602 - } 603 - 604 - #else 605 - 606 - #define agnx_pci_suspend NULL 607 - #define agnx_pci_resume NULL 608 - 609 - #endif /* CONFIG_PM */ 610 - 611 - 612 - static struct pci_driver agnx_pci_driver = { 613 - .name = "agnx-pci", 614 - .id_table = agnx_pci_id_tbl, 615 - .probe = agnx_pci_probe, 616 - .remove = __devexit_p(agnx_pci_remove), 617 - .suspend = agnx_pci_suspend, 618 - .resume = agnx_pci_resume, 619 - }; 620 - 621 - static int __init agnx_pci_init(void) 622 - { 623 - AGNX_TRACE; 624 - return pci_register_driver(&agnx_pci_driver); 625 - } 626 - 627 - static void __exit agnx_pci_exit(void) 628 - { 629 - AGNX_TRACE; 630 - pci_unregister_driver(&agnx_pci_driver); 631 - } 632 - 633 - 634 - module_init(agnx_pci_init); 635 - module_exit(agnx_pci_exit);
-960
drivers/staging/agnx/phy.c
··· 1 - /** 2 - * Airgo MIMO wireless driver 3 - * 4 - * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com> 5 - 6 - * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer 7 - * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin 8 - 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation. 12 - */ 13 - 14 - #include <linux/init.h> 15 - #include <linux/etherdevice.h> 16 - #include <linux/pci.h> 17 - #include <linux/delay.h> 18 - #include "agnx.h" 19 - #include "debug.h" 20 - #include "phy.h" 21 - #include "table.h" 22 - #include "sta.h" 23 - #include "xmit.h" 24 - 25 - u8 read_from_eeprom(struct agnx_priv *priv, u16 address) 26 - { 27 - void __iomem *ctl = priv->ctl; 28 - struct agnx_eeprom cmd; 29 - u32 reg; 30 - 31 - memset(&cmd, 0, sizeof(cmd)); 32 - cmd.cmd = EEPROM_CMD_READ << AGNX_EEPROM_COMMAND_SHIFT; 33 - cmd.address = address; 34 - /* Verify that the Status bit is clear */ 35 - /* Read Command and Address are written to the Serial Interface */ 36 - iowrite32(*(__le32 *)&cmd, ctl + AGNX_CIR_SERIALITF); 37 - /* Wait for the Status bit to clear again */ 38 - eeprom_delay(); 39 - /* Read from Data */ 40 - reg = ioread32(ctl + AGNX_CIR_SERIALITF); 41 - 42 - cmd = *(struct agnx_eeprom *)&reg; 43 - 44 - return cmd.data; 45 - } 46 - 47 - static int card_full_reset(struct agnx_priv *priv) 48 - { 49 - void __iomem *ctl = priv->ctl; 50 - u32 reg; 51 - AGNX_TRACE; 52 - 53 - reg = agnx_read32(ctl, AGNX_CIR_BLKCTL); 54 - agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x80); 55 - reg = agnx_read32(ctl, AGNX_CIR_BLKCTL); 56 - return 0; 57 - } 58 - 59 - inline void enable_power_saving(struct agnx_priv *priv) 60 - { 61 - void __iomem *ctl = priv->ctl; 62 - u32 reg; 63 - 64 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 65 - reg &= ~0x8; 66 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 67 - } 68 - 69 - inline void disable_power_saving(struct agnx_priv *priv) 70 - { 71 - void __iomem *ctl = priv->ctl; 72 - u32 reg; 73 - 74 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 75 - reg |= 0x8; 76 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 77 - } 78 - 79 - 80 - void disable_receiver(struct agnx_priv *priv) 81 - { 82 - void __iomem *ctl = priv->ctl; 83 - AGNX_TRACE; 84 - 85 - /* FIXME Disable the receiver */ 86 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0); 87 - /* Set gain control reset */ 88 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1); 89 - /* Reset gain control reset */ 90 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0); 91 - } 92 - 93 - 94 - /* Fixme this shoule be disable RX, above is enable RX */ 95 - void enable_receiver(struct agnx_priv *priv) 96 - { 97 - void __iomem *ctl = priv->ctl; 98 - AGNX_TRACE; 99 - 100 - /* Set adaptive gain control discovery mode */ 101 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 102 - /* Set gain control reset */ 103 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1); 104 - /* Clear gain control reset */ 105 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0); 106 - } 107 - 108 - static void mac_address_set(struct agnx_priv *priv) 109 - { 110 - void __iomem *ctl = priv->ctl; 111 - u8 *mac_addr = priv->mac_addr; 112 - u32 reg; 113 - 114 - /* FIXME */ 115 - reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3]; 116 - iowrite32(reg, ctl + AGNX_RXM_MACHI); 117 - reg = (mac_addr[4] << 8) | mac_addr[5]; 118 - iowrite32(reg, ctl + AGNX_RXM_MACLO); 119 - } 120 - 121 - static void receiver_bssid_set(struct agnx_priv *priv, const u8 *bssid) 122 - { 123 - void __iomem *ctl = priv->ctl; 124 - u32 reg; 125 - 126 - disable_receiver(priv); 127 - /* FIXME */ 128 - reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3]; 129 - iowrite32(reg, ctl + AGNX_RXM_BSSIDHI); 130 - reg = (bssid[4] << 8) | bssid[5]; 131 - iowrite32(reg, ctl + AGNX_RXM_BSSIDLO); 132 - 133 - /* Enable the receiver */ 134 - enable_receiver(priv); 135 - 136 - /* Clear the TSF */ 137 - /* agnx_write32(ctl, AGNX_TXM_TSFLO, 0x0); */ 138 - /* agnx_write32(ctl, AGNX_TXM_TSFHI, 0x0); */ 139 - /* Clear the TBTT */ 140 - agnx_write32(ctl, AGNX_TXM_TBTTLO, 0x0); 141 - agnx_write32(ctl, AGNX_TXM_TBTTHI, 0x0); 142 - disable_receiver(priv); 143 - } /* receiver_bssid_set */ 144 - 145 - static void band_management_init(struct agnx_priv *priv) 146 - { 147 - void __iomem *ctl = priv->ctl; 148 - void __iomem *data = priv->data; 149 - u32 reg; 150 - int i; 151 - AGNX_TRACE; 152 - 153 - agnx_write32(ctl, AGNX_BM_TXWADDR, AGNX_PDU_TX_WQ); 154 - agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0); 155 - memset_io(data + AGNX_PDUPOOL, 0x0, AGNX_PDUPOOL_SIZE); 156 - agnx_write32(ctl, AGNX_BM_BMCTL, 0x200); 157 - 158 - agnx_write32(ctl, AGNX_BM_CIPDUWCNT, 0x40); 159 - agnx_write32(ctl, AGNX_BM_SPPDUWCNT, 0x2); 160 - agnx_write32(ctl, AGNX_BM_RFPPDUWCNT, 0x0); 161 - agnx_write32(ctl, AGNX_BM_RHPPDUWCNT, 0x22); 162 - 163 - /* FIXME Initialize the Free Pool Linked List */ 164 - /* 1. Write the Address of the Next Node ((0x41800 + node*size)/size) 165 - to the first word of each node. */ 166 - for (i = 0; i < PDU_FREE_CNT; i++) { 167 - iowrite32((AGNX_PDU_FREE + (i+1)*PDU_SIZE)/PDU_SIZE, 168 - data + AGNX_PDU_FREE + (PDU_SIZE * i)); 169 - /* The last node should be set to 0x0 */ 170 - if ((i + 1) == PDU_FREE_CNT) 171 - memset_io(data + AGNX_PDU_FREE + (PDU_SIZE * i), 172 - 0x0, PDU_SIZE); 173 - } 174 - 175 - /* Head is First Pool address (0x41800) / size (0x80) */ 176 - agnx_write32(ctl, AGNX_BM_FPLHP, AGNX_PDU_FREE/PDU_SIZE); 177 - /* Tail is Last Pool Address (0x47f80) / size (0x80) */ 178 - agnx_write32(ctl, AGNX_BM_FPLTP, 0x47f80/PDU_SIZE); 179 - /* Count is Number of Nodes in the Pool (0xd0) */ 180 - agnx_write32(ctl, AGNX_BM_FPCNT, PDU_FREE_CNT); 181 - 182 - /* Start all workqueue */ 183 - agnx_write32(ctl, AGNX_BM_CIWQCTL, 0x80000); 184 - agnx_write32(ctl, AGNX_BM_CPULWCTL, 0x80000); 185 - agnx_write32(ctl, AGNX_BM_CPUHWCTL, 0x80000); 186 - agnx_write32(ctl, AGNX_BM_CPUTXWCTL, 0x80000); 187 - agnx_write32(ctl, AGNX_BM_CPURXWCTL, 0x80000); 188 - agnx_write32(ctl, AGNX_BM_SPRXWCTL, 0x80000); 189 - agnx_write32(ctl, AGNX_BM_SPTXWCTL, 0x80000); 190 - agnx_write32(ctl, AGNX_BM_RFPWCTL, 0x80000); 191 - 192 - /* Enable the Band Management */ 193 - reg = agnx_read32(ctl, AGNX_BM_BMCTL); 194 - reg |= 0x1; 195 - agnx_write32(ctl, AGNX_BM_BMCTL, reg); 196 - } /* band_managment_init */ 197 - 198 - 199 - static void system_itf_init(struct agnx_priv *priv) 200 - { 201 - void __iomem *ctl = priv->ctl; 202 - u32 reg; 203 - AGNX_TRACE; 204 - 205 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x0); 206 - agnx_write32(ctl, AGNX_PM_TESTPHY, 0x11e143a); 207 - 208 - if (priv->revid == 0) { 209 - reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE); 210 - reg |= 0x11; 211 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg); 212 - } 213 - /* ??? What is that means? it should difference for differice type 214 - of cards */ 215 - agnx_write32(ctl, AGNX_CIR_SERIALITF, 0xfff81006); 216 - 217 - agnx_write32(ctl, AGNX_SYSITF_GPIOIN, 0x1f0000); 218 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5); 219 - reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN); 220 - } 221 - 222 - static void encryption_init(struct agnx_priv *priv) 223 - { 224 - void __iomem *ctl = priv->ctl; 225 - AGNX_TRACE; 226 - 227 - agnx_write32(ctl, AGNX_ENCRY_WEPKEY0, 0x0); 228 - agnx_write32(ctl, AGNX_ENCRY_WEPKEY1, 0x0); 229 - agnx_write32(ctl, AGNX_ENCRY_WEPKEY2, 0x0); 230 - agnx_write32(ctl, AGNX_ENCRY_WEPKEY3, 0x0); 231 - agnx_write32(ctl, AGNX_ENCRY_CCMRECTL, 0x8); 232 - } 233 - 234 - static void tx_management_init(struct agnx_priv *priv) 235 - { 236 - void __iomem *ctl = priv->ctl; 237 - void __iomem *data = priv->data; 238 - u32 reg; 239 - AGNX_TRACE; 240 - 241 - /* Fill out the ComputationalEngineLookupTable 242 - * starting at memory #2 offset 0x800 243 - */ 244 - tx_engine_lookup_tbl_init(priv); 245 - memset_io(data + 0x1000, 0, 0xfe0); 246 - /* Enable Transmission Management Functions */ 247 - agnx_write32(ctl, AGNX_TXM_ETMF, 0x3ff); 248 - /* Write 0x3f to Transmission Template */ 249 - agnx_write32(ctl, AGNX_TXM_TXTEMP, 0x3f); 250 - 251 - if (priv->revid >= 2) 252 - agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e140a0b); 253 - else 254 - agnx_write32(ctl, AGNX_TXM_SIFSPIFS, 0x1e190a0b); 255 - 256 - reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS); 257 - reg &= 0xff00; 258 - reg |= 0xb; 259 - agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg); 260 - reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS); 261 - reg &= 0xffff00ff; 262 - reg |= 0xa00; 263 - agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg); 264 - /* Enable TIFS */ 265 - agnx_write32(ctl, AGNX_TXM_CTL, 0x40000); 266 - 267 - reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS); 268 - reg &= 0xff00ffff; 269 - reg |= 0x510000; 270 - agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg); 271 - reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY); 272 - reg &= 0xff00ffff; 273 - agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg); 274 - reg = agnx_read32(ctl, AGNX_TXM_TIFSEIFS); 275 - reg &= 0x00ffffff; 276 - reg |= 0x1c000000; 277 - agnx_write32(ctl, AGNX_TXM_TIFSEIFS, reg); 278 - reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY); 279 - reg &= 0x00ffffff; 280 - reg |= 0x01000000; 281 - agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg); 282 - 283 - /* # Set DIF 0-1,2-3,4-5,6-7 to defaults */ 284 - agnx_write32(ctl, AGNX_TXM_DIF01, 0x321d321d); 285 - agnx_write32(ctl, AGNX_TXM_DIF23, 0x321d321d); 286 - agnx_write32(ctl, AGNX_TXM_DIF45, 0x321d321d); 287 - agnx_write32(ctl, AGNX_TXM_DIF67, 0x321d321d); 288 - 289 - /* Max Ack timeout limit */ 290 - agnx_write32(ctl, AGNX_TXM_MAXACKTIM, 0x1e19); 291 - /* Max RX Data Timeout count, */ 292 - reg = agnx_read32(ctl, AGNX_TXM_MAXRXTIME); 293 - reg &= 0xffff0000; 294 - reg |= 0xff; 295 - agnx_write32(ctl, AGNX_TXM_MAXRXTIME, reg); 296 - 297 - /* CF poll RX Timeout count */ 298 - reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM); 299 - reg &= 0xffff; 300 - reg |= 0xff0000; 301 - agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg); 302 - 303 - /* Max Timeout Exceeded count, */ 304 - reg = agnx_read32(ctl, AGNX_TXM_MAXTIMOUT); 305 - reg &= 0xff00ffff; 306 - reg |= 0x190000; 307 - agnx_write32(ctl, AGNX_TXM_MAXTIMOUT, reg); 308 - 309 - /* CF ack timeout limit for 11b */ 310 - reg = agnx_read32(ctl, AGNX_TXM_CFACKT11B); 311 - reg &= 0xff00; 312 - reg |= 0x1e; 313 - agnx_write32(ctl, AGNX_TXM_CFACKT11B, reg); 314 - 315 - /* Max CF Poll Timeout Count */ 316 - reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM); 317 - reg &= 0xffff0000; 318 - reg |= 0x19; 319 - agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg); 320 - /* CF Poll RX Timeout Count */ 321 - reg = agnx_read32(ctl, AGNX_TXM_CFPOLLRXTIM); 322 - reg &= 0xffff0000; 323 - reg |= 0x1e; 324 - agnx_write32(ctl, AGNX_TXM_CFPOLLRXTIM, reg); 325 - 326 - /* # write default to */ 327 - /* 1. Schedule Empty Count */ 328 - agnx_write32(ctl, AGNX_TXM_SCHEMPCNT, 0x5); 329 - /* 2. CFP Period Count */ 330 - agnx_write32(ctl, AGNX_TXM_CFPERCNT, 0x1); 331 - /* 3. CFP MDV */ 332 - agnx_write32(ctl, AGNX_TXM_CFPMDV, 0x10000); 333 - 334 - /* Probe Delay */ 335 - reg = agnx_read32(ctl, AGNX_TXM_PROBDELAY); 336 - reg &= 0xffff0000; 337 - reg |= 0x400; 338 - agnx_write32(ctl, AGNX_TXM_PROBDELAY, reg); 339 - 340 - /* Max CCA count Slot */ 341 - reg = agnx_read32(ctl, AGNX_TXM_MAXCCACNTSLOT); 342 - reg &= 0xffff00ff; 343 - reg |= 0x900; 344 - agnx_write32(ctl, AGNX_TXM_MAXCCACNTSLOT, reg); 345 - 346 - /* Slot limit/1 msec Limit */ 347 - reg = agnx_read32(ctl, AGNX_TXM_SLOTLIMIT); 348 - reg &= 0xff00ffff; 349 - reg |= 0x140077; 350 - agnx_write32(ctl, AGNX_TXM_SLOTLIMIT, reg); 351 - 352 - /* # Set CW #(0-7) to default */ 353 - agnx_write32(ctl, AGNX_TXM_CW0, 0xff0007); 354 - agnx_write32(ctl, AGNX_TXM_CW1, 0xff0007); 355 - agnx_write32(ctl, AGNX_TXM_CW2, 0xff0007); 356 - agnx_write32(ctl, AGNX_TXM_CW3, 0xff0007); 357 - agnx_write32(ctl, AGNX_TXM_CW4, 0xff0007); 358 - agnx_write32(ctl, AGNX_TXM_CW5, 0xff0007); 359 - agnx_write32(ctl, AGNX_TXM_CW6, 0xff0007); 360 - agnx_write32(ctl, AGNX_TXM_CW7, 0xff0007); 361 - 362 - /* # Set Short/Long limit #(0-7) to default */ 363 - agnx_write32(ctl, AGNX_TXM_SLBEALIM0, 0xa000a); 364 - agnx_write32(ctl, AGNX_TXM_SLBEALIM1, 0xa000a); 365 - agnx_write32(ctl, AGNX_TXM_SLBEALIM2, 0xa000a); 366 - agnx_write32(ctl, AGNX_TXM_SLBEALIM3, 0xa000a); 367 - agnx_write32(ctl, AGNX_TXM_SLBEALIM4, 0xa000a); 368 - agnx_write32(ctl, AGNX_TXM_SLBEALIM5, 0xa000a); 369 - agnx_write32(ctl, AGNX_TXM_SLBEALIM6, 0xa000a); 370 - agnx_write32(ctl, AGNX_TXM_SLBEALIM7, 0xa000a); 371 - 372 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 373 - reg |= 0x1400; 374 - agnx_write32(ctl, AGNX_TXM_CTL, reg); 375 - /* Wait for bit 0 in Control Reg to clear */ 376 - udelay(80); 377 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 378 - /* Or 0x18000 to Control reg */ 379 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 380 - reg |= 0x18000; 381 - agnx_write32(ctl, AGNX_TXM_CTL, reg); 382 - /* Wait for bit 0 in Control Reg to clear */ 383 - udelay(80); 384 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 385 - 386 - /* Set Listen Interval Count to default */ 387 - agnx_write32(ctl, AGNX_TXM_LISINTERCNT, 0x1); 388 - /* Set DTIM period count to default */ 389 - agnx_write32(ctl, AGNX_TXM_DTIMPERICNT, 0x2000); 390 - } /* tx_management_init */ 391 - 392 - static void rx_management_init(struct agnx_priv *priv) 393 - { 394 - void __iomem *ctl = priv->ctl; 395 - AGNX_TRACE; 396 - 397 - /* Initialize the Routing Table */ 398 - routing_table_init(priv); 399 - 400 - if (priv->revid >= 3) { 401 - agnx_write32(ctl, 0x2074, 0x1f171710); 402 - agnx_write32(ctl, 0x2078, 0x10100d0d); 403 - agnx_write32(ctl, 0x207c, 0x11111010); 404 - } else { 405 - agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0); 406 - } 407 - agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00); 408 - } 409 - 410 - 411 - static void agnx_timer_init(struct agnx_priv *priv) 412 - { 413 - void __iomem *ctl = priv->ctl; 414 - AGNX_TRACE; 415 - 416 - /* /\* Write 0x249f00 (tick duration?) to Timer 1 *\/ */ 417 - /* agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x249f00); */ 418 - /* /\* Write 0xe2 to Timer 1 Control *\/ */ 419 - /* agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0xe2); */ 420 - 421 - /* Write 0x249f00 (tick duration?) to Timer 1 */ 422 - agnx_write32(ctl, AGNX_TIMCTL_TIMER1, 0x0); 423 - /* Write 0xe2 to Timer 1 Control */ 424 - agnx_write32(ctl, AGNX_TIMCTL_TIM1CTL, 0x0); 425 - 426 - iowrite32(0xFFFFFFFF, priv->ctl + AGNX_TXM_BEACON_CTL); 427 - } 428 - 429 - static void power_manage_init(struct agnx_priv *priv) 430 - { 431 - void __iomem *ctl = priv->ctl; 432 - u32 reg; 433 - AGNX_TRACE; 434 - 435 - agnx_write32(ctl, AGNX_PM_MACMSW, 0x1f); 436 - agnx_write32(ctl, AGNX_PM_RFCTL, 0x1f); 437 - 438 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 439 - reg &= 0xf00f; 440 - reg |= 0xa0; 441 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 442 - 443 - if (priv->revid >= 3) { 444 - reg = agnx_read32(ctl, AGNX_PM_SOFTRST); 445 - reg |= 0x18; 446 - agnx_write32(ctl, AGNX_PM_SOFTRST, reg); 447 - } 448 - } /* power_manage_init */ 449 - 450 - 451 - static void gain_ctlcnt_init(struct agnx_priv *priv) 452 - { 453 - void __iomem *ctl = priv->ctl; 454 - u32 reg; 455 - AGNX_TRACE; 456 - 457 - agnx_write32(ctl, AGNX_GCR_TRACNT5, 0x119); 458 - agnx_write32(ctl, AGNX_GCR_TRACNT6, 0x118); 459 - agnx_write32(ctl, AGNX_GCR_TRACNT7, 0x117); 460 - 461 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 462 - reg |= 0x8; 463 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 464 - 465 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 466 - reg &= ~0x8; 467 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 468 - 469 - agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x0); 470 - 471 - /* FIXME Write the initial Station Descriptor for the card */ 472 - sta_init(priv, LOCAL_STAID); 473 - sta_init(priv, BSSID_STAID); 474 - 475 - /* Enable staion 0 and 1 can do TX */ 476 - /* It seemed if we set other bit to 1 the bit 0 will 477 - be auto change to 0 */ 478 - agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1); 479 - /* agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */ 480 - } /* gain_ctlcnt_init */ 481 - 482 - 483 - static void phy_init(struct agnx_priv *priv) 484 - { 485 - void __iomem *ctl = priv->ctl; 486 - void __iomem *data = priv->data; 487 - u32 reg; 488 - AGNX_TRACE; 489 - 490 - /* Load InitialGainTable */ 491 - gain_table_init(priv); 492 - 493 - agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000); 494 - 495 - /* Clear the following offsets in Memory Range #2: */ 496 - memset_io(data + 0x5040, 0, 0xa * 4); 497 - memset_io(data + 0x5080, 0, 0xa * 4); 498 - memset_io(data + 0x50c0, 0, 0xa * 4); 499 - memset_io(data + 0x5400, 0, 0x80 * 4); 500 - memset_io(data + 0x6000, 0, 0x280 * 4); 501 - memset_io(data + 0x7000, 0, 0x280 * 4); 502 - memset_io(data + 0x8000, 0, 0x280 * 4); 503 - 504 - /* Initialize the Following Registers According to PCI Revision ID */ 505 - if (priv->revid == 0) { 506 - /* fixme the part hasn't been update but below has been update 507 - based on WGM511 */ 508 - agnx_write32(ctl, AGNX_ACI_LEN, 0xf); 509 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x1d); 510 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x3); 511 - agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11); 512 - agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0); 513 - agnx_write32(ctl, AGNX_GCR_THD0A, 0x64); 514 - agnx_write32(ctl, AGNX_GCR_THD0AL, 0x4b); 515 - agnx_write32(ctl, AGNX_GCR_THD0B, 0x4b); 516 - agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14); 517 - agnx_write32(ctl, AGNX_GCR_DSAT, 0x24); 518 - agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8); 519 - agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a); 520 - agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3); 521 - agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd); 522 - agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1); 523 - agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7); 524 - agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28); 525 - agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28); 526 - reg = agnx_read32(ctl, AGNX_GCR_CWDETEC); 527 - reg |= 0x1; 528 - agnx_write32(ctl, AGNX_GCR_CWDETEC, reg); 529 - agnx_write32(ctl, AGNX_GCR_0X38, 0x1e); 530 - agnx_write32(ctl, AGNX_GCR_BOACT, 0x26); 531 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 532 - agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3); 533 - agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3); 534 - agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3); 535 - agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3); 536 - agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x0); 537 - agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x0); 538 - agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x0); 539 - agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x0); 540 - agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10); 541 - agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1); 542 - agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0x1); 543 - agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190); 544 - agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x78); 545 - agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x1c); 546 - agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0); 547 - agnx_write32(ctl, AGNX_GCR_THCD, 0x0); 548 - agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x1); 549 - agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0); 550 - agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f); 551 - agnx_write32(ctl, AGNX_GCR_THJUMP, 0x14); 552 - agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0); 553 - agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x30); 554 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x32); 555 - agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19); 556 - agnx_write32(ctl, AGNX_GCR_0X14c, 0x0); 557 - agnx_write32(ctl, AGNX_GCR_0X150, 0x0); 558 - agnx_write32(ctl, 0x9400, 0x0); 559 - agnx_write32(ctl, 0x940c, 0x6ff); 560 - agnx_write32(ctl, 0x9428, 0xa0); 561 - agnx_write32(ctl, 0x9434, 0x0); 562 - agnx_write32(ctl, 0x9c04, 0x15); 563 - agnx_write32(ctl, 0x9c0c, 0x7f); 564 - agnx_write32(ctl, 0x9c34, 0x0); 565 - agnx_write32(ctl, 0xc000, 0x38d); 566 - agnx_write32(ctl, 0x14018, 0x0); 567 - agnx_write32(ctl, 0x16000, 0x1); 568 - agnx_write32(ctl, 0x11004, 0x0); 569 - agnx_write32(ctl, 0xec54, 0xa); 570 - agnx_write32(ctl, 0xec1c, 0x5); 571 - } else if (priv->revid > 0) { 572 - agnx_write32(ctl, AGNX_ACI_LEN, 0xf); 573 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21); 574 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 575 - agnx_write32(ctl, AGNX_ACI_AICCHA0OVE, 0x11); 576 - agnx_write32(ctl, AGNX_ACI_AICCHA1OVE, 0x0); 577 - agnx_write32(ctl, AGNX_GCR_DUNSAT, 0x14); 578 - agnx_write32(ctl, AGNX_GCR_DSAT, 0x24); 579 - agnx_write32(ctl, AGNX_GCR_DFIRCAL, 0x8); 580 - agnx_write32(ctl, AGNX_GCR_DGCTL11A, 0x1a); 581 - agnx_write32(ctl, AGNX_GCR_DGCTL11B, 0x3); 582 - agnx_write32(ctl, AGNX_GCR_GAININIT, 0xd); 583 - agnx_write32(ctl, AGNX_GCR_THNOSIG, 0x1); 584 - agnx_write32(ctl, AGNX_GCR_COARSTEP, 0x7); 585 - agnx_write32(ctl, AGNX_GCR_SIFST11A, 0x28); 586 - agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28); 587 - agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0); 588 - agnx_write32(ctl, AGNX_GCR_0X38, 0x1e); 589 - /* agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/ 590 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 591 - 592 - agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32); 593 - agnx_write32(ctl, AGNX_GCR_THCAP11B, 0x32); 594 - agnx_write32(ctl, AGNX_GCR_THCAPRX11A, 0x32); 595 - agnx_write32(ctl, AGNX_GCR_THCAPRX11B, 0x32); 596 - agnx_write32(ctl, AGNX_GCR_THLEVDRO, 0x10); 597 - agnx_write32(ctl, AGNX_GCR_MAXRXTIME11A, 0x1ad); 598 - agnx_write32(ctl, AGNX_GCR_MAXRXTIME11B, 0xa10); 599 - agnx_write32(ctl, AGNX_GCR_CORRTIME, 0x190); 600 - agnx_write32(ctl, AGNX_GCR_CORRDROP, 0x0); 601 - agnx_write32(ctl, AGNX_GCR_THCD, 0x0); 602 - agnx_write32(ctl, AGNX_GCR_THCS, 0x0); 603 - agnx_write32(ctl, AGNX_GCR_MAXPOWDIFF, 0x4); 604 - agnx_write32(ctl, AGNX_GCR_TESTBUS, 0x0); 605 - agnx_write32(ctl, AGNX_GCR_THJUMP, 0x1e); 606 - agnx_write32(ctl, AGNX_GCR_THPOWER, 0x0); 607 - agnx_write32(ctl, AGNX_GCR_THPOWCLIP, 0x2a); 608 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c); 609 - agnx_write32(ctl, AGNX_GCR_THRX11BPOWMIN, 0x19); 610 - agnx_write32(ctl, AGNX_GCR_0X14c, 0x0); 611 - agnx_write32(ctl, AGNX_GCR_0X150, 0x0); 612 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 613 - agnx_write32(ctl, AGNX_GCR_WATCHDOG, 0x37); 614 - agnx_write32(ctl, 0x9400, 0x0); 615 - agnx_write32(ctl, 0x940c, 0x6ff); 616 - agnx_write32(ctl, 0x9428, 0xa0); 617 - agnx_write32(ctl, 0x9434, 0x0); 618 - agnx_write32(ctl, 0x9c04, 0x15); 619 - agnx_write32(ctl, 0x9c0c, 0x7f); 620 - agnx_write32(ctl, 0x9c34, 0x0); 621 - agnx_write32(ctl, 0xc000, 0x38d); 622 - agnx_write32(ctl, 0x14014, 0x1000); 623 - agnx_write32(ctl, 0x14018, 0x0); 624 - agnx_write32(ctl, 0x16000, 0x1); 625 - agnx_write32(ctl, 0x11004, 0x0); 626 - agnx_write32(ctl, 0xec54, 0xa); 627 - agnx_write32(ctl, 0xec1c, 0x50); 628 - } else if (priv->revid > 1) { 629 - reg = agnx_read32(ctl, 0xec18); 630 - reg |= 0x8; 631 - agnx_write32(ctl, 0xec18, reg); 632 - } 633 - 634 - /* Write the TX Fir Coefficient Table */ 635 - tx_fir_table_init(priv); 636 - 637 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 638 - reg &= ~0x8; 639 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 640 - reg = agnx_read32(ctl, AGNX_PM_PLLCTL); 641 - reg |= 0x1; 642 - agnx_write32(ctl, AGNX_PM_PLLCTL, reg); 643 - 644 - /* reg = agnx_read32(ctl, 0x1a030); */ 645 - /* reg &= ~0x4; */ 646 - /* agnx_write32(ctl, 0x1a030, reg); */ 647 - 648 - agnx_write32(ctl, AGNX_GCR_TRACNT4, 0x113); 649 - } /* phy_init */ 650 - 651 - static void chip_init(struct agnx_priv *priv) 652 - { 653 - void __iomem *ctl = priv->ctl; 654 - u32 reg; 655 - AGNX_TRACE; 656 - 657 - band_management_init(priv); 658 - 659 - rf_chips_init(priv); 660 - 661 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 662 - reg |= 0x8; 663 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 664 - 665 - /* Initialize the PHY */ 666 - phy_init(priv); 667 - 668 - encryption_init(priv); 669 - 670 - tx_management_init(priv); 671 - 672 - rx_management_init(priv); 673 - 674 - power_manage_init(priv); 675 - 676 - /* Initialize the Timers */ 677 - agnx_timer_init(priv); 678 - 679 - /* Write 0xc390bf9 to Interrupt Mask (Disable TX) */ 680 - reg = 0xc390bf9 & ~IRQ_TX_BEACON; 681 - reg &= ~IRQ_TX_DISABLE; 682 - agnx_write32(ctl, AGNX_INT_MASK, reg); 683 - 684 - reg = agnx_read32(ctl, AGNX_CIR_BLKCTL); 685 - reg |= 0x800; 686 - agnx_write32(ctl, AGNX_CIR_BLKCTL, reg); 687 - 688 - /* set it when need get multicast enable? */ 689 - agnx_write32(ctl, AGNX_BM_MTSM, 0xff); 690 - } /* chip_init */ 691 - 692 - 693 - static inline void set_promis_and_managed(struct agnx_priv *priv) 694 - { 695 - void __iomem *ctl = priv->ctl; 696 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2); 697 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10 | 0x2); 698 - } 699 - static inline void set_learn_mode(struct agnx_priv *priv) 700 - { 701 - void __iomem *ctl = priv->ctl; 702 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x8); 703 - } 704 - static inline void set_scan_mode(struct agnx_priv *priv) 705 - { 706 - void __iomem *ctl = priv->ctl; 707 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x20); 708 - } 709 - static inline void set_promiscuous_mode(struct agnx_priv *priv) 710 - { 711 - void __iomem *ctl = priv->ctl; 712 - /* agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x210);*/ 713 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x10); 714 - } 715 - static inline void set_managed_mode(struct agnx_priv *priv) 716 - { 717 - void __iomem *ctl = priv->ctl; 718 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x2); 719 - } 720 - static inline void set_adhoc_mode(struct agnx_priv *priv) 721 - { 722 - void __iomem *ctl = priv->ctl; 723 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, 0x0); 724 - } 725 - 726 - #if 0 727 - static void unknow_register_write(struct agnx_priv *priv) 728 - { 729 - void __iomem *ctl = priv->ctl; 730 - 731 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x0, 0x3e); 732 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4, 0xb2); 733 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x8, 0x140); 734 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0xc, 0x1C0); 735 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x10, 0x1FF); 736 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x14, 0x1DD); 737 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x18, 0x15F); 738 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x1c, 0xA1); 739 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x20, 0x3E7); 740 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x24, 0x36B); 741 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x28, 0x348); 742 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x2c, 0x37D); 743 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x30, 0x3DE); 744 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x34, 0x36); 745 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x38, 0x64); 746 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x3c, 0x57); 747 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x40, 0x23); 748 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x44, 0x3ED); 749 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x48, 0x3C9); 750 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x4c, 0x3CA); 751 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x50, 0x3E7); 752 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x54, 0x8); 753 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x58, 0x1F); 754 - agnx_write32(ctl, AGNX_UNKNOWN_BASE + 0x5c, 0x1a); 755 - } 756 - #endif 757 - 758 - static void card_interface_init(struct agnx_priv *priv) 759 - { 760 - void __iomem *ctl = priv->ctl; 761 - u8 bssid[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 762 - u32 reg; 763 - unsigned int i; 764 - AGNX_TRACE; 765 - 766 - might_sleep(); 767 - /* Clear RX Control and Enable RX queues */ 768 - agnx_write32(ctl, AGNX_CIR_RXCTL, 0x8); 769 - 770 - might_sleep(); 771 - /* Do a full reset of the card */ 772 - card_full_reset(priv); 773 - might_sleep(); 774 - 775 - /* Check and set Card Endianness */ 776 - reg = ioread32(priv->ctl + AGNX_CIR_ENDIAN); 777 - /* TODO If not 0xB3B2B1B0 set to 0xB3B2B1B0 */ 778 - printk(KERN_INFO PFX "CIR_ENDIAN is %x\n", reg); 779 - 780 - 781 - /* Config the eeprom */ 782 - agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x7000086); 783 - udelay(10); 784 - reg = agnx_read32(ctl, AGNX_CIR_SERIALITF); 785 - 786 - 787 - agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033); 788 - reg = agnx_read32(ctl, 0xec50); 789 - reg |= 0xf; 790 - agnx_write32(ctl, 0xec50, reg); 791 - agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0); 792 - 793 - 794 - reg = agnx_read32(ctl, AGNX_SYSITF_GPIOIN); 795 - udelay(10); 796 - reg = agnx_read32(ctl, AGNX_CIR_SERIALITF); 797 - 798 - /* Dump the eeprom */ 799 - do { 800 - char eeprom[0x100000/0x100]; 801 - 802 - for (i = 0; i < 0x100000; i += 0x100) { 803 - agnx_write32(ctl, AGNX_CIR_SERIALITF, 0x3000000 + i); 804 - udelay(13); 805 - reg = agnx_read32(ctl, AGNX_CIR_SERIALITF); 806 - udelay(70); 807 - reg = agnx_read32(ctl, AGNX_CIR_SERIALITF); 808 - eeprom[i/0x100] = reg & 0xFF; 809 - udelay(10); 810 - } 811 - print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom, 812 - ARRAY_SIZE(eeprom)); 813 - } while (0); 814 - 815 - spi_rc_write(ctl, RF_CHIP0, 0x26); 816 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 817 - 818 - /* Initialize the system interface */ 819 - system_itf_init(priv); 820 - 821 - might_sleep(); 822 - /* Chip Initialization (Polaris) */ 823 - chip_init(priv); 824 - might_sleep(); 825 - 826 - /* Calibrate the antennae */ 827 - antenna_calibrate(priv); 828 - 829 - reg = agnx_read32(ctl, 0xec50); 830 - reg &= ~0x40; 831 - agnx_write32(ctl, 0xec50, reg); 832 - agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0); 833 - agnx_write32(ctl, AGNX_PM_PLLCTL, 0x1); 834 - 835 - reg = agnx_read32(ctl, AGNX_BM_BMCTL); 836 - reg |= 0x8000; 837 - agnx_write32(ctl, AGNX_BM_BMCTL, reg); 838 - enable_receiver(priv); 839 - reg = agnx_read32(ctl, AGNX_SYSITF_SYSMODE); 840 - reg |= 0x200; 841 - agnx_write32(ctl, AGNX_SYSITF_SYSMODE, reg); 842 - enable_receiver(priv); 843 - 844 - might_sleep(); 845 - /* Initialize Gain Control Counts */ 846 - gain_ctlcnt_init(priv); 847 - 848 - /* Write Initial Station Power Template for this station(#0) */ 849 - sta_power_init(priv, LOCAL_STAID); 850 - 851 - might_sleep(); 852 - /* Initialize the rx,td,tm rings, for each node in the ring */ 853 - fill_rings(priv); 854 - 855 - might_sleep(); 856 - 857 - 858 - agnx_write32(ctl, AGNX_PM_SOFTRST, 0x80000033); 859 - agnx_write32(ctl, 0xec50, 0xc); 860 - agnx_write32(ctl, AGNX_PM_SOFTRST, 0x0); 861 - 862 - /* FIXME Initialize the transmit control register */ 863 - agnx_write32(ctl, AGNX_TXM_CTL, 0x194c1); 864 - 865 - enable_receiver(priv); 866 - 867 - might_sleep(); 868 - /* FIXME Set the Receive Control Mac Address to card address */ 869 - mac_address_set(priv); 870 - enable_receiver(priv); 871 - might_sleep(); 872 - 873 - /* Set the recieve request rate */ 874 - /* FIXME Enable the request */ 875 - /* Check packet length */ 876 - /* Set maximum packet length */ 877 - /* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */ 878 - /* enable_receiver(priv); */ 879 - 880 - /* Set the Receiver BSSID */ 881 - receiver_bssid_set(priv, bssid); 882 - 883 - /* FIXME Set to managed mode */ 884 - set_managed_mode(priv); 885 - /* set_promiscuous_mode(priv); */ 886 - /* set_scan_mode(priv); */ 887 - /* set_learn_mode(priv); */ 888 - /* set_promis_and_managed(priv); */ 889 - /* set_adhoc_mode(priv); */ 890 - 891 - /* Set the recieve request rate */ 892 - /* Check packet length */ 893 - agnx_write32(ctl, AGNX_RXM_REQRATE, 0x08000000); 894 - reg = agnx_read32(ctl, AGNX_RXM_REQRATE); 895 - /* Set maximum packet length */ 896 - reg |= 0x00195e00; 897 - agnx_write32(ctl, AGNX_RXM_REQRATE, reg); 898 - 899 - /* Configure the RX and TX interrupt */ 900 - reg = ENABLE_RX_INTERRUPT | RX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE; 901 - agnx_write32(ctl, AGNX_CIR_RXCFG, reg); 902 - /* FIXME */ 903 - reg = ENABLE_TX_INTERRUPT | TX_CACHE_LINE | FRAG_LEN_2048 | FRAG_BE; 904 - agnx_write32(ctl, AGNX_CIR_TXCFG, reg); 905 - 906 - /* Enable RX TX Interrupts */ 907 - agnx_write32(ctl, AGNX_CIR_RXCTL, 0x80); 908 - agnx_write32(ctl, AGNX_CIR_TXMCTL, 0x80); 909 - agnx_write32(ctl, AGNX_CIR_TXDCTL, 0x80); 910 - 911 - /* FIXME Set the master control interrupt in block control */ 912 - agnx_write32(ctl, AGNX_CIR_BLKCTL, 0x800); 913 - 914 - /* Enable RX and TX queues */ 915 - reg = agnx_read32(ctl, AGNX_CIR_RXCTL); 916 - reg |= 0x8; 917 - agnx_write32(ctl, AGNX_CIR_RXCTL, reg); 918 - reg = agnx_read32(ctl, AGNX_CIR_TXMCTL); 919 - reg |= 0x8; 920 - agnx_write32(ctl, AGNX_CIR_TXMCTL, reg); 921 - reg = agnx_read32(ctl, AGNX_CIR_TXDCTL); 922 - reg |= 0x8; 923 - agnx_write32(ctl, AGNX_CIR_TXDCTL, reg); 924 - 925 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5); 926 - /* FIXME */ 927 - /* unknow_register_write(priv); */ 928 - /* Update local card hash entry */ 929 - hash_write(priv, priv->mac_addr, LOCAL_STAID); 930 - 931 - might_sleep(); 932 - 933 - /* FIXME */ 934 - agnx_set_channel(priv, 1); 935 - might_sleep(); 936 - } /* agnx_card_interface_init */ 937 - 938 - 939 - void agnx_hw_init(struct agnx_priv *priv) 940 - { 941 - AGNX_TRACE; 942 - might_sleep(); 943 - card_interface_init(priv); 944 - } 945 - 946 - int agnx_hw_reset(struct agnx_priv *priv) 947 - { 948 - return card_full_reset(priv); 949 - } 950 - 951 - int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len) 952 - { 953 - AGNX_TRACE; 954 - return 0; 955 - } 956 - 957 - void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid) 958 - { 959 - receiver_bssid_set(priv, bssid); 960 - }
-409
drivers/staging/agnx/phy.h
··· 1 - #ifndef AGNX_PHY_H_ 2 - #define AGNX_PHY_H_ 3 - 4 - #include "agnx.h" 5 - 6 - /* Transmission Managment Registers */ 7 - #define AGNX_TXM_BASE 0x0000 8 - #define AGNX_TXM_CTL 0x0000 /* control register */ 9 - #define AGNX_TXM_ETMF 0x0004 /* enable transmission management functions */ 10 - #define AGNX_TXM_TXTEMP 0x0008 /* transmission template */ 11 - #define AGNX_TXM_RETRYSTAID 0x000c /* Retry Station ID */ 12 - #define AGNX_TXM_TIMESTAMPLO 0x0010 /* Timestamp Lo */ 13 - #define AGNX_TXM_TIMESTAMPHI 0x0014 /* Timestamp Hi */ 14 - #define AGNX_TXM_TXDELAY 0x0018 /* tx delay */ 15 - #define AGNX_TXM_TBTTLO 0x0020 /* tbtt Lo */ 16 - #define AGNX_TXM_TBTTHI 0x0024 /* tbtt Hi */ 17 - #define AGNX_TXM_BEAINTER 0x0028 /* Beacon Interval */ 18 - #define AGNX_TXM_NAV 0x0030 /* NAV */ 19 - #define AGNX_TXM_CFPMDV 0x0034 /* CFP MDV */ 20 - #define AGNX_TXM_CFPERCNT 0x0038 /* CFP period count */ 21 - #define AGNX_TXM_PROBDELAY 0x003c /* probe delay */ 22 - #define AGNX_TXM_LISINTERCNT 0x0040 /* listen interval count */ 23 - #define AGNX_TXM_DTIMPERICNT 0x004c /* DTIM period count */ 24 - 25 - #define AGNX_TXM_BEACON_CTL 0x005c /* beacon control */ 26 - 27 - #define AGNX_TXM_SCHEMPCNT 0x007c /* schedule empty count */ 28 - #define AGNX_TXM_MAXTIMOUT 0x0084 /* max timeout exceed count */ 29 - #define AGNX_TXM_MAXCFPTIM 0x0088 /* max CF poll timeout count */ 30 - #define AGNX_TXM_MAXRXTIME 0x008c /* max RX timeout count */ 31 - #define AGNX_TXM_MAXACKTIM 0x0090 /* max ACK timeout count */ 32 - #define AGNX_TXM_DIF01 0x00a0 /* DIF 0-1 */ 33 - #define AGNX_TXM_DIF23 0x00a4 /* DIF 2-3 */ 34 - #define AGNX_TXM_DIF45 0x00a8 /* DIF 4-5 */ 35 - #define AGNX_TXM_DIF67 0x00ac /* DIF 6-7 */ 36 - #define AGNX_TXM_SIFSPIFS 0x00b0 /* SIFS/PIFS */ 37 - #define AGNX_TXM_TIFSEIFS 0x00b4 /* TIFS/EIFS */ 38 - #define AGNX_TXM_MAXCCACNTSLOT 0x00b8 /* max CCA count slot */ 39 - #define AGNX_TXM_SLOTLIMIT 0x00bc /* slot limit/1 msec limit */ 40 - #define AGNX_TXM_CFPOLLRXTIM 0x00f0 /* CF poll RX timeout count */ 41 - #define AGNX_TXM_CFACKT11B 0x00f4 /* CF ack timeout limit for 11b */ 42 - #define AGNX_TXM_CW0 0x0100 /* CW 0 */ 43 - #define AGNX_TXM_SLBEALIM0 0x0108 /* short/long beacon limit 0 */ 44 - #define AGNX_TXM_CW1 0x0120 /* CW 1 */ 45 - #define AGNX_TXM_SLBEALIM1 0x0128 /* short/long beacon limit 1 */ 46 - #define AGNX_TXM_CW2 0x0140 /* CW 2 */ 47 - #define AGNX_TXM_SLBEALIM2 0x0148 /* short/long beacon limit 2 */ 48 - #define AGNX_TXM_CW3 0x0160 /* CW 3 */ 49 - #define AGNX_TXM_SLBEALIM3 0x0168 /* short/long beacon limit 3 */ 50 - #define AGNX_TXM_CW4 0x0180 /* CW 4 */ 51 - #define AGNX_TXM_SLBEALIM4 0x0188 /* short/long beacon limit 4 */ 52 - #define AGNX_TXM_CW5 0x01a0 /* CW 5 */ 53 - #define AGNX_TXM_SLBEALIM5 0x01a8 /* short/long beacon limit 5 */ 54 - #define AGNX_TXM_CW6 0x01c0 /* CW 6 */ 55 - #define AGNX_TXM_SLBEALIM6 0x01c8 /* short/long beacon limit 6 */ 56 - #define AGNX_TXM_CW7 0x01e0 /* CW 7 */ 57 - #define AGNX_TXM_SLBEALIM7 0x01e8 /* short/long beacon limit 7 */ 58 - #define AGNX_TXM_BEACONTEMP 0x1000 /* beacon template */ 59 - #define AGNX_TXM_STAPOWTEMP 0x1a00 /* Station Power Template */ 60 - 61 - /* Receive Management Control Registers */ 62 - #define AGNX_RXM_BASE 0x2000 63 - #define AGNX_RXM_REQRATE 0x2000 /* requested rate */ 64 - #define AGNX_RXM_MACHI 0x2004 /* first 4 bytes of mac address */ 65 - #define AGNX_RXM_MACLO 0x2008 /* last 2 bytes of mac address */ 66 - #define AGNX_RXM_BSSIDHI 0x200c /* bssid hi */ 67 - #define AGNX_RXM_BSSIDLO 0x2010 /* bssid lo */ 68 - #define AGNX_RXM_HASH_CMD_FLAG 0x2014 /* Flags for the RX Hash Command Default:0 */ 69 - #define AGNX_RXM_HASH_CMD_HIGH 0x2018 /* The High half of the Hash Command */ 70 - #define AGNX_RXM_HASH_CMD_LOW 0x201c /* The Low half of the Hash Command */ 71 - #define AGNX_RXM_ROUTAB 0x2020 /* routing table */ 72 - #define ROUTAB_SUBTYPE_SHIFT 24 73 - #define ROUTAB_TYPE_SHIFT 28 74 - #define ROUTAB_STATUS_SHIFT 30 75 - #define ROUTAB_RW_SHIFT 31 76 - #define ROUTAB_ROUTE_DROP 0xf00000 /* Drop */ 77 - #define ROUTAB_ROUTE_CPU 0x400000 /* CPU */ 78 - #define ROUTAB_ROUTE_ENCRY 0x500800 /* Encryption */ 79 - #define ROUTAB_ROUTE_RFP 0x800000 /* RFP */ 80 - 81 - #define ROUTAB_TYPE_MANAG 0x0 /* Management */ 82 - #define ROUTAB_TYPE_CTL 0x1 /* Control */ 83 - #define ROUTAB_TYPE_DATA 0x2 /* Data */ 84 - 85 - #define ROUTAB_SUBTYPE_DATA 0x0 86 - #define ROUTAB_SUBTYPE_DATAACK 0x1 87 - #define ROUTAB_SUBTYPE_DATAPOLL 0x2 88 - #define ROUTAB_SUBTYPE_DATAPOLLACK 0x3 89 - #define ROUTAB_SUBTYPE_NULL 0x4 /* NULL */ 90 - #define ROUTAB_SUBTYPE_NULLACK 0x5 91 - #define ROUTAB_SUBTYPE_NULLPOLL 0x6 92 - #define ROUTAB_SUBTYPE_NULLPOLLACK 0x7 93 - #define ROUTAB_SUBTYPE_QOSDATA 0x8 /* QOS DATA */ 94 - #define ROUTAB_SUBTYPE_QOSDATAACK 0x9 95 - #define ROUTAB_SUBTYPE_QOSDATAPOLL 0xa 96 - #define ROUTAB_SUBTYPE_QOSDATAACKPOLL 0xb 97 - #define ROUTAB_SUBTYPE_QOSNULL 0xc 98 - #define ROUTAB_SUBTYPE_QOSNULLACK 0xd 99 - #define ROUTAB_SUBTYPE_QOSNULLPOLL 0xe 100 - #define ROUTAB_SUBTYPE_QOSNULLPOLLACK 0xf 101 - #define AGNX_RXM_DELAY11 0x2024 /* delay 11(AB) */ 102 - #define AGNX_RXM_SOF_CNT 0x2028 /* SOF Count */ 103 - #define AGNX_RXM_FRAG_CNT 0x202c /* Fragment Count*/ 104 - #define AGNX_RXM_FCS_CNT 0x2030 /* FCS Count */ 105 - #define AGNX_RXM_BSSID_MISS_CNT 0x2034 /* BSSID Miss Count */ 106 - #define AGNX_RXM_PDU_ERR_CNT 0x2038 /* PDU Error Count */ 107 - #define AGNX_RXM_DEST_MISS_CNT 0x203C /* Destination Miss Count */ 108 - #define AGNX_RXM_DROP_CNT 0x2040 /* Drop Count */ 109 - #define AGNX_RXM_ABORT_CNT 0x2044 /* Abort Count */ 110 - #define AGNX_RXM_RELAY_CNT 0x2048 /* Relay Count */ 111 - #define AGNX_RXM_HASH_MISS_CNT 0x204c /* Hash Miss Count */ 112 - #define AGNX_RXM_SA_HI 0x2050 /* Address of received packet Hi */ 113 - #define AGNX_RXM_SA_LO 0x2054 /* Address of received packet Lo */ 114 - #define AGNX_RXM_HASH_DUMP_LST 0x2100 /* Contains Hash Data */ 115 - #define AGNX_RXM_HASH_DUMP_MST 0x2104 /* Contains Hash Data */ 116 - #define AGNX_RXM_HASH_DUMP_DATA 0x2108 /* The Station ID to dump */ 117 - 118 - 119 - /* Encryption Managment */ 120 - #define AGNX_ENCRY_BASE 0x2400 121 - #define AGNX_ENCRY_WEPKEY0 0x2440 /* wep key #0 */ 122 - #define AGNX_ENCRY_WEPKEY1 0x2444 /* wep key #1 */ 123 - #define AGNX_ENCRY_WEPKEY2 0x2448 /* wep key #2 */ 124 - #define AGNX_ENCRY_WEPKEY3 0x244c /* wep key #3 */ 125 - #define AGNX_ENCRY_CCMRECTL 0x2460 /* ccm replay control */ 126 - 127 - 128 - /* Band Management Registers */ 129 - #define AGNX_BM_BASE 0x2c00 130 - #define AGNX_BM_BMCTL 0x2c00 /* band management control */ 131 - #define AGNX_BM_TXWADDR 0x2c18 /* tx workqueue address start */ 132 - #define AGNX_BM_TXTOPEER 0x2c24 /* transmit to peers */ 133 - #define AGNX_BM_FPLHP 0x2c2c /* free pool list head pointer */ 134 - #define AGNX_BM_FPLTP 0x2c30 /* free pool list tail pointer */ 135 - #define AGNX_BM_FPCNT 0x2c34 /* free pool count */ 136 - #define AGNX_BM_CIPDUWCNT 0x2c38 /* card interface pdu workqueue count */ 137 - #define AGNX_BM_SPPDUWCNT 0x2c3c /* sp pdu workqueue count */ 138 - #define AGNX_BM_RFPPDUWCNT 0x2c40 /* rfp pdu workqueue count */ 139 - #define AGNX_BM_RHPPDUWCNT 0x2c44 /* rhp pdu workqueue count */ 140 - #define AGNX_BM_CIWQCTL 0x2c48 /* Card Interface WorkQueue Control */ 141 - #define AGNX_BM_CPUTXWCTL 0x2c50 /* cpu tx workqueue control */ 142 - #define AGNX_BM_CPURXWCTL 0x2c58 /* cpu rx workqueue control */ 143 - #define AGNX_BM_CPULWCTL 0x2c60 /* cpu low workqueue control */ 144 - #define AGNX_BM_CPUHWCTL 0x2c68 /* cpu high workqueue control */ 145 - #define AGNX_BM_SPTXWCTL 0x2c70 /* sp tx workqueue control */ 146 - #define AGNX_BM_SPRXWCTL 0x2c78 /* sp rx workqueue control */ 147 - #define AGNX_BM_RFPWCTL 0x2c80 /* RFP workqueue control */ 148 - #define AGNX_BM_MTSM 0x2c90 /* Multicast Transmit Station Mask */ 149 - 150 - /* Card Interface Registers (32bits) */ 151 - #define AGNX_CIR_BASE 0x3000 152 - #define AGNX_CIR_BLKCTL 0x3000 /* block control*/ 153 - #define AGNX_STAT_TX 0x1 154 - #define AGNX_STAT_RX 0x2 155 - #define AGNX_STAT_X 0x4 156 - /* Below two interrupt flags will be set by our but not CPU or the card */ 157 - #define AGNX_STAT_TXD 0x10 158 - #define AGNX_STAT_TXM 0x20 159 - 160 - #define AGNX_CIR_ADDRWIN 0x3004 /* Addressable Windows*/ 161 - #define AGNX_CIR_ENDIAN 0x3008 /* card endianness */ 162 - #define AGNX_CIR_SERIALITF 0x3020 /* serial interface */ 163 - #define AGNX_CIR_RXCFG 0x3040 /* receive config */ 164 - #define ENABLE_RX_INTERRUPT 0x20 165 - #define RX_CACHE_LINE 0x8 166 - /* the RX fragment length */ 167 - #define FRAG_LEN_256 0x0 /* 256B */ 168 - #define FRAG_LEN_512 0x1 169 - #define FRAG_LEN_1024 0x2 170 - #define FRAG_LEN_2048 0x3 171 - #define FRAG_BE 0x10 172 - #define AGNX_CIR_RXCTL 0x3050 /* receive control */ 173 - /* memory address, chipside */ 174 - #define AGNX_CIR_RXCMSTART 0x3054 /* receive client memory start */ 175 - #define AGNX_CIR_RXCMEND 0x3058 /* receive client memory end */ 176 - /* memory address, pci */ 177 - #define AGNX_CIR_RXHOSTADDR 0x3060 /* receive hostside address */ 178 - /* memory address, chipside */ 179 - #define AGNX_CIR_RXCLIADDR 0x3064 /* receive clientside address */ 180 - #define AGNX_CIR_RXDMACTL 0x3068 /* receive dma control */ 181 - #define AGNX_CIR_TXCFG 0x3080 /* transmit config */ 182 - #define AGNX_CIR_TXMCTL 0x3090 /* Transmit Management Control */ 183 - #define ENABLE_TX_INTERRUPT 0x20 184 - #define TX_CACHE_LINE 0x8 185 - #define AGNX_CIR_TXMSTART 0x3094 /* Transmit Management Start */ 186 - #define AGNX_CIR_TXMEND 0x3098 /* Transmit Management End */ 187 - #define AGNX_CIR_TXDCTL 0x30a0 /* transmit data control */ 188 - /* memeory address, chipset */ 189 - #define AGNX_CIR_TXDSTART 0x30a4 /* transmit data start */ 190 - #define AGNX_CIR_TXDEND 0x30a8 /* transmit data end */ 191 - #define AGNX_CIR_TXMHADDR 0x30b0 /* Transmit Management Hostside Address */ 192 - #define AGNX_CIR_TXMCADDR 0x30b4 /* Transmit Management Clientside Address */ 193 - #define AGNX_CIR_TXDMACTL 0x30b8 /* transmit dma control */ 194 - 195 - 196 - /* Power Managment Unit */ 197 - #define AGNX_PM_BASE 0x3c00 198 - #define AGNX_PM_PMCTL 0x3c00 /* PM Control*/ 199 - #define AGNX_PM_MACMSW 0x3c08 /* MAC Manual Slow Work Enable */ 200 - #define AGNX_PM_RFCTL 0x3c0c /* RF Control */ 201 - #define AGNX_PM_PHYMW 0x3c14 /* Phy Mannal Work */ 202 - #define AGNX_PM_SOFTRST 0x3c18 /* PMU Soft Reset */ 203 - #define AGNX_PM_PLLCTL 0x3c1c /* PMU PLL control*/ 204 - #define AGNX_PM_TESTPHY 0x3c24 /* PMU Test Phy */ 205 - 206 - 207 - /* Interrupt Control interface */ 208 - #define AGNX_INT_BASE 0x4000 209 - #define AGNX_INT_STAT 0x4000 /* interrupt status */ 210 - #define AGNX_INT_MASK 0x400c /* interrupt mask */ 211 - /* FIXME */ 212 - #define IRQ_TX_BEACON 0x1 /* TX Beacon */ 213 - #define IRQ_TX_RETRY 0x8 /* TX Retry Interrupt */ 214 - #define IRQ_TX_ACTIVITY 0x10 /* TX Activity */ 215 - #define IRQ_RX_ACTIVITY 0x20 /* RX Activity */ 216 - /* FIXME I guess that instead RX a none exist staion's packet or 217 - the station hasn't been init */ 218 - #define IRQ_RX_X 0x40 219 - #define IRQ_RX_Y 0x80 /* RX ? */ 220 - #define IRQ_RX_HASHHIT 0x100 /* RX Hash Hit */ 221 - #define IRQ_RX_FRAME 0x200 /* RX Frame */ 222 - #define IRQ_ERR_INT 0x400 /* Error Interrupt */ 223 - #define IRQ_TX_QUE_FULL 0x800 /* TX Workqueue Full */ 224 - #define IRQ_BANDMAN_ERR 0x10000 /* Bandwidth Management Error */ 225 - #define IRQ_TX_DISABLE 0x20000 /* TX Disable */ 226 - #define IRQ_RX_IVASESKEY 0x80000 /* RX Invalid Session Key */ 227 - #define IRQ_RX_KEYIDMIS 0x100000 /* RX key ID Mismatch */ 228 - #define IRQ_REP_THHIT 0x200000 /* Replay Threshold Hit */ 229 - #define IRQ_TIMER1 0x4000000 /* Timer1 */ 230 - #define IRQ_TIMER_CNT 0x10000000 /* Timer Count */ 231 - #define IRQ_PHY_FASTINT 0x20000000 /* Phy Fast Interrupt */ 232 - #define IRQ_PHY_SLOWINT 0x40000000 /* Phy Slow Interrupt */ 233 - #define IRQ_OTHER 0x80000000 /* Unknow interrupt */ 234 - #define AGNX_IRQ_ALL 0xffffffff 235 - 236 - /* System Interface */ 237 - #define AGNX_SYSITF_BASE 0x4400 238 - #define AGNX_SYSITF_SYSMODE 0x4400 /* system mode */ 239 - #define AGNX_SYSITF_GPIOIN 0x4410 /* GPIO In */ 240 - /* PIN lines for leds? */ 241 - #define AGNX_SYSITF_GPIOUT 0x4414 /* GPIO Out */ 242 - 243 - /* Timer Control */ 244 - #define AGNX_TIMCTL_TIMER1 0x4800 /* Timer 1 */ 245 - #define AGNX_TIMCTL_TIM1CTL 0x4808 /* Timer 1 Control */ 246 - 247 - 248 - /* Antenna Calibration Interface */ 249 - #define AGNX_ACI_BASE 0x5000 250 - #define AGNX_ACI_MODE 0x5000 /* Mode */ 251 - #define AGNX_ACI_MEASURE 0x5004 /* Measure */ 252 - #define AGNX_ACI_SELCHAIN 0x5008 /* Select Chain */ 253 - #define AGNX_ACI_LEN 0x500c /* Length */ 254 - #define AGNX_ACI_TIMER1 0x5018 /* Timer 1 */ 255 - #define AGNX_ACI_TIMER2 0x501c /* Timer 2 */ 256 - #define AGNX_ACI_OFFSET 0x5020 /* Offset */ 257 - #define AGNX_ACI_STATUS 0x5030 /* Status */ 258 - #define CALI_IDLE 0x0 259 - #define CALI_DONE 0x1 260 - #define CALI_BUSY 0x2 261 - #define CALI_ERR 0x3 262 - #define AGNX_ACI_AICCHA0OVE 0x5034 /* AIC Channel 0 Override */ 263 - #define AGNX_ACI_AICCHA1OVE 0x5038 /* AIC Channel 1 Override */ 264 - 265 - /* Gain Control Registers */ 266 - #define AGNX_GCR_BASE 0x9000 267 - /* threshold of primary antenna */ 268 - #define AGNX_GCR_THD0A 0x9000 /* threshold? D0 A */ 269 - /* low threshold of primary antenna */ 270 - #define AGNX_GCR_THD0AL 0x9004 /* threshold? D0 A low */ 271 - /* threshold of secondary antenna */ 272 - #define AGNX_GCR_THD0B 0x9008 /* threshold? D0_B */ 273 - #define AGNX_GCR_DUNSAT 0x900c /* d unsaturated */ 274 - #define AGNX_GCR_DSAT 0x9010 /* d saturated */ 275 - #define AGNX_GCR_DFIRCAL 0x9014 /* D Fir/Cal */ 276 - #define AGNX_GCR_DGCTL11A 0x9018 /* d gain control 11a */ 277 - #define AGNX_GCR_DGCTL11B 0x901c /* d gain control 11b */ 278 - /* strength of gain */ 279 - #define AGNX_GCR_GAININIT 0x9020 /* gain initialization */ 280 - #define AGNX_GCR_THNOSIG 0x9024 /* threhold no signal */ 281 - #define AGNX_GCR_COARSTEP 0x9028 /* coarse stepping */ 282 - #define AGNX_GCR_SIFST11A 0x902c /* sifx time 11a */ 283 - #define AGNX_GCR_SIFST11B 0x9030 /* sifx time 11b */ 284 - #define AGNX_GCR_CWDETEC 0x9034 /* cw detection */ 285 - #define AGNX_GCR_0X38 0x9038 /* ???? */ 286 - #define AGNX_GCR_BOACT 0x903c /* BO Active */ 287 - #define AGNX_GCR_BOINACT 0x9040 /* BO Inactive */ 288 - #define AGNX_GCR_BODYNA 0x9044 /* BO dynamic */ 289 - /* 802.11 mode(a,b,g) */ 290 - #define AGNX_GCR_DISCOVMOD 0x9048 /* discovery mode */ 291 - #define AGNX_GCR_NLISTANT 0x904c /* number of listening antenna */ 292 - #define AGNX_GCR_NACTIANT 0x9050 /* number of active antenna */ 293 - #define AGNX_GCR_NMEASANT 0x9054 /* number of measuring antenna */ 294 - #define AGNX_GCR_NCAPTANT 0x9058 /* number of capture antenna */ 295 - #define AGNX_GCR_THCAP11A 0x905c /* threshold capture 11a */ 296 - #define AGNX_GCR_THCAP11B 0x9060 /* threshold capture 11b */ 297 - #define AGNX_GCR_THCAPRX11A 0x9064 /* threshold capture rx 11a */ 298 - #define AGNX_GCR_THCAPRX11B 0x9068 /* threshold capture rx 11b */ 299 - #define AGNX_GCR_THLEVDRO 0x906c /* threshold level drop */ 300 - #define AGNX_GCR_GAINSET0 0x9070 /* Gainset 0 */ 301 - #define AGNX_GCR_GAINSET1 0x9074 /* Gainset 1 */ 302 - #define AGNX_GCR_GAINSET2 0x9078 /* Gainset 2 */ 303 - #define AGNX_GCR_MAXRXTIME11A 0x907c /* maximum rx time 11a */ 304 - #define AGNX_GCR_MAXRXTIME11B 0x9080 /* maximum rx time 11b */ 305 - #define AGNX_GCR_CORRTIME 0x9084 /* correction time */ 306 - /* reset the subsystem, 0 = disable, 1 = enable */ 307 - #define AGNX_GCR_RSTGCTL 0x9088 /* reset gain control */ 308 - /* channel receiving */ 309 - #define AGNX_GCR_RXCHANEL 0x908c /* receive channel */ 310 - #define AGNX_GCR_NOISE0 0x9090 /* Noise 0 */ 311 - #define AGNX_GCR_NOISE1 0x9094 /* Noise 1 */ 312 - #define AGNX_GCR_NOISE2 0x9098 /* Noise 2 */ 313 - #define AGNX_GCR_SIGHTH 0x909c /* Signal High Threshold */ 314 - #define AGNX_GCR_SIGLTH 0x90a0 /* Signal Low Threshold */ 315 - #define AGNX_GCR_CORRDROP 0x90a4 /* correction drop */ 316 - /* threshold of tertiay antenna */ 317 - #define AGNX_GCR_THCD 0x90a8 /* threshold? CD */ 318 - #define AGNX_GCR_THCS 0x90ac /* threshold? CS */ 319 - #define AGNX_GCR_MAXPOWDIFF 0x90b8 /* maximum power difference */ 320 - #define AGNX_GCR_TRACNT4 0x90ec /* Transition Count 4 */ 321 - #define AGNX_GCR_TRACNT5 0x90f0 /* transition count 5 */ 322 - #define AGNX_GCR_TRACNT6 0x90f4 /* transition count 6 */ 323 - #define AGNX_GCR_TRACNT7 0x90f8 /* transition coutn 7 */ 324 - #define AGNX_GCR_TESTBUS 0x911c /* test bus */ 325 - #define AGNX_GCR_CHAINNUM 0x9120 /* Number of Chains */ 326 - #define AGNX_GCR_ANTCFG 0x9124 /* Antenna Config */ 327 - #define AGNX_GCR_THJUMP 0x912c /* threhold jump */ 328 - #define AGNX_GCR_THPOWER 0x9130 /* threshold power */ 329 - #define AGNX_GCR_THPOWCLIP 0x9134 /* threshold power clip*/ 330 - #define AGNX_GCR_FORCECTLCLK 0x9138 /* Force Gain Control Clock */ 331 - #define AGNX_GCR_GAINSETWRITE 0x913c /* Gainset Write */ 332 - #define AGNX_GCR_THD0BTFEST 0x9140 /* threshold d0 b tf estimate */ 333 - #define AGNX_GCR_THRX11BPOWMIN 0x9144 /* threshold rx 11b power minimum */ 334 - #define AGNX_GCR_0X14c 0x914c /* ?? */ 335 - #define AGNX_GCR_0X150 0x9150 /* ?? */ 336 - #define AGNX_GCR_RXOVERIDE 0x9194 /* recieve override */ 337 - #define AGNX_GCR_WATCHDOG 0x91b0 /* watchdog timeout */ 338 - 339 - 340 - /* Spi Interface */ 341 - #define AGNX_SPI_BASE 0xdc00 342 - #define AGNX_SPI_CFG 0xdc00 /* spi configuration */ 343 - /* Only accept 16 bits */ 344 - #define AGNX_SPI_WMSW 0xdc04 /* write most significant word */ 345 - /* Only accept 16 bits */ 346 - #define AGNX_SPI_WLSW 0xdc08 /* write least significant word */ 347 - #define AGNX_SPI_CTL 0xdc0c /* spi control */ 348 - #define AGNX_SPI_RMSW 0xdc10 /* read most significant word */ 349 - #define AGNX_SPI_RLSW 0xdc14 /* read least significant word */ 350 - /* SPI Control Mask */ 351 - #define SPI_READ_CTL 0x4000 /* read control */ 352 - #define SPI_BUSY_CTL 0x8000 /* busy control */ 353 - /* RF and synth chips in spi */ 354 - #define RF_CHIP0 0x400 355 - #define RF_CHIP1 0x800 356 - #define RF_CHIP2 0x1000 357 - #define SYNTH_CHIP 0x2000 358 - 359 - /* Unknown register */ 360 - #define AGNX_UNKNOWN_BASE 0x7800 361 - 362 - /* FIXME MonitorGain */ 363 - #define AGNX_MONGCR_BASE 0x12000 364 - 365 - /* Gain Table */ 366 - #define AGNX_GAIN_TABLE 0x12400 367 - 368 - /* The initial FIR coefficient table */ 369 - #define AGNX_FIR_BASE 0x19804 370 - 371 - #define AGNX_ENGINE_LOOKUP_TBL 0x800 372 - 373 - /* eeprom commands */ 374 - #define EEPROM_CMD_NULL 0x0 /* NULL */ 375 - #define EEPROM_CMD_WRITE 0x2 /* write */ 376 - #define EEPROM_CMD_READ 0x3 /* read */ 377 - #define EEPROM_CMD_STATUSREAD 0x5 /* status register read */ 378 - #define EEPROM_CMD_WRITEENABLE 0x6 /* write enable */ 379 - #define EEPROM_CMD_CONFIGURE 0x7 /* configure */ 380 - 381 - #define EEPROM_DATAFORCOFIGURE 0x6 /* ??? */ 382 - 383 - /* eeprom address */ 384 - #define EEPROM_ADDR_SUBVID 0x0 /* Sub Vendor ID */ 385 - #define EEPROM_ADDR_SUBSID 0x2 /* Sub System ID */ 386 - #define EEPROM_ADDR_MACADDR 0x146 /* MAC Address */ 387 - #define EEPROM_ADDR_LOTYPE 0x14f /* LO type */ 388 - 389 - struct agnx_eeprom { 390 - u8 data; /* date */ 391 - u16 address; /* address in EEPROM */ 392 - u8 cmd; /* command, unknown, status */ 393 - } __attribute__((__packed__)); 394 - 395 - #define AGNX_EEPROM_COMMAND_SHIFT 5 396 - #define AGNX_EEPROM_COMMAND_STAT 0x01 397 - 398 - void disable_receiver(struct agnx_priv *priv); 399 - void enable_receiver(struct agnx_priv *priv); 400 - u8 read_from_eeprom(struct agnx_priv *priv, u16 address); 401 - void agnx_hw_init(struct agnx_priv *priv); 402 - int agnx_hw_reset(struct agnx_priv *priv); 403 - int agnx_set_ssid(struct agnx_priv *priv, u8 *ssid, size_t ssid_len); 404 - void agnx_set_bssid(struct agnx_priv *priv, const u8 *bssid); 405 - void enable_power_saving(struct agnx_priv *priv); 406 - void disable_power_saving(struct agnx_priv *priv); 407 - void calibrate_antenna_period(unsigned long data); 408 - 409 - #endif /* AGNX_PHY_H_ */
-893
drivers/staging/agnx/rf.c
··· 1 - /** 2 - * Airgo MIMO wireless driver 3 - * 4 - * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com> 5 - 6 - * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer 7 - * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin 8 - 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation; 12 - */ 13 - 14 - #include <linux/pci.h> 15 - #include <linux/delay.h> 16 - #include "agnx.h" 17 - #include "debug.h" 18 - #include "phy.h" 19 - #include "table.h" 20 - 21 - /* FIXME! */ 22 - static inline void spi_write(void __iomem *region, u32 chip_ids, u32 sw, 23 - u16 size, u32 control) 24 - { 25 - u32 reg; 26 - u32 lsw = sw & 0xffff; /* lower 16 bits of sw*/ 27 - u32 msw = sw >> 16; /* high 16 bits of sw */ 28 - 29 - /* FIXME Write Most Significant Word of the 32bit data to MSW */ 30 - /* FIXME And Least Significant Word to LSW */ 31 - iowrite32((lsw), region + AGNX_SPI_WLSW); 32 - iowrite32((msw), region + AGNX_SPI_WMSW); 33 - reg = chip_ids | size | control; 34 - /* Write chip id(s), write size and busy control to Control Register */ 35 - iowrite32((reg), region + AGNX_SPI_CTL); 36 - /* Wait for Busy control to clear */ 37 - spi_delay(); 38 - } 39 - 40 - /* 41 - * Write to SPI Synth register 42 - */ 43 - static inline void spi_sy_write(void __iomem *region, u32 chip_ids, u32 sw) 44 - { 45 - /* FIXME the size 0x15 is a magic value*/ 46 - spi_write(region, chip_ids, sw, 0x15, SPI_BUSY_CTL); 47 - } 48 - 49 - /* 50 - * Write to SPI RF register 51 - */ 52 - static inline void spi_rf_write(void __iomem *region, u32 chip_ids, u32 sw) 53 - { 54 - /* FIXME the size 0xd is a magic value*/ 55 - spi_write(region, chip_ids, sw, 0xd, SPI_BUSY_CTL); 56 - } /* spi_rf_write */ 57 - 58 - /* 59 - * Write to SPI with Read Control bit set 60 - */ 61 - inline void spi_rc_write(void __iomem *region, u32 chip_ids, u32 sw) 62 - { 63 - /* FIXME the size 0xe5 is a magic value */ 64 - spi_write(region, chip_ids, sw, 0xe5, SPI_BUSY_CTL|SPI_READ_CTL); 65 - } 66 - 67 - /* Get the active chains's count */ 68 - static int get_active_chains(struct agnx_priv *priv) 69 - { 70 - void __iomem *ctl = priv->ctl; 71 - int num = 0; 72 - u32 reg; 73 - AGNX_TRACE; 74 - 75 - spi_rc_write(ctl, RF_CHIP0, 0x21); 76 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 77 - if (reg == 1) 78 - num++; 79 - 80 - spi_rc_write(ctl, RF_CHIP1, 0x21); 81 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 82 - if (reg == 1) 83 - num++; 84 - 85 - spi_rc_write(ctl, RF_CHIP2, 0x21); 86 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 87 - if (reg == 1) 88 - num++; 89 - 90 - spi_rc_write(ctl, RF_CHIP0, 0x26); 91 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 92 - if (0x33 != reg) 93 - printk(KERN_WARNING PFX "Unmatched rf chips result\n"); 94 - 95 - return num; 96 - } /* get_active_chains */ 97 - 98 - void rf_chips_init(struct agnx_priv *priv) 99 - { 100 - void __iomem *ctl = priv->ctl; 101 - u32 reg; 102 - int num; 103 - AGNX_TRACE; 104 - 105 - if (priv->revid == 1) { 106 - reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT); 107 - reg |= 0x8; 108 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg); 109 - } 110 - 111 - /* Set SPI clock speed to 200NS */ 112 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 113 - reg &= ~0xF; 114 - reg |= 0x3; 115 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 116 - 117 - /* Set SPI clock speed to 50NS */ 118 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 119 - reg &= ~0xF; 120 - reg |= 0x1; 121 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 122 - 123 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1101); 124 - 125 - num = get_active_chains(priv); 126 - printk(KERN_INFO PFX "Active chains are %d\n", num); 127 - 128 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 129 - reg &= ~0xF; 130 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 131 - 132 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1908); 133 - } /* rf_chips_init */ 134 - 135 - 136 - static u32 channel_tbl[15][9] = { 137 - {0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 138 - {1, 0x00, 0x00, 0x624, 0x00, 0x1a4, 0x28, 0x00, 0x1e}, 139 - {2, 0x00, 0x00, 0x615, 0x00, 0x1ae, 0x28, 0x00, 0x1e}, 140 - {3, 0x00, 0x00, 0x61a, 0x00, 0x1ae, 0x28, 0x00, 0x1e}, 141 - {4, 0x00, 0x00, 0x61f, 0x00, 0x1ae, 0x28, 0x00, 0x1e}, 142 - {5, 0x00, 0x00, 0x624, 0x00, 0x1ae, 0x28, 0x00, 0x1e}, 143 - {6, 0x00, 0x00, 0x61f, 0x00, 0x1b3, 0x28, 0x00, 0x1e}, 144 - {7, 0x00, 0x00, 0x624, 0x00, 0x1b3, 0x28, 0x00, 0x1e}, 145 - {8, 0x00, 0x00, 0x629, 0x00, 0x1b3, 0x28, 0x00, 0x1e}, 146 - {9, 0x00, 0x00, 0x624, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 147 - {10, 0x00, 0x00, 0x629, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 148 - {11, 0x00, 0x00, 0x62e, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 149 - {12, 0x00, 0x00, 0x633, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 150 - {13, 0x00, 0x00, 0x628, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 151 - {14, 0x00, 0x00, 0x644, 0x00, 0x1b8, 0x28, 0x00, 0x1e}, 152 - }; 153 - 154 - 155 - static inline void 156 - channel_tbl_write(struct agnx_priv *priv, unsigned int channel, unsigned int reg_num) 157 - { 158 - void __iomem *ctl = priv->ctl; 159 - u32 reg; 160 - 161 - reg = channel_tbl[channel][reg_num]; 162 - reg <<= 4; 163 - reg |= reg_num; 164 - spi_sy_write(ctl, SYNTH_CHIP, reg); 165 - } 166 - 167 - static void synth_freq_set(struct agnx_priv *priv, unsigned int channel) 168 - { 169 - void __iomem *ctl = priv->ctl; 170 - u32 reg; 171 - AGNX_TRACE; 172 - 173 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 174 - 175 - /* Set the Clock bits to 50NS */ 176 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 177 - reg &= ~0xF; 178 - reg |= 0x1; 179 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 180 - 181 - /* Write 0x00c0 to LSW and 0x3 to MSW of Synth Chip */ 182 - spi_sy_write(ctl, SYNTH_CHIP, 0x300c0); 183 - 184 - spi_sy_write(ctl, SYNTH_CHIP, 0x32); 185 - 186 - /* # Write to Register 1 on the Synth Chip */ 187 - channel_tbl_write(priv, channel, 1); 188 - /* # Write to Register 3 on the Synth Chip */ 189 - channel_tbl_write(priv, channel, 3); 190 - /* # Write to Register 6 on the Synth Chip */ 191 - channel_tbl_write(priv, channel, 6); 192 - /* # Write to Register 5 on the Synth Chip */ 193 - channel_tbl_write(priv, channel, 5); 194 - /* # Write to register 8 on the Synth Chip */ 195 - channel_tbl_write(priv, channel, 8); 196 - 197 - /* FIXME Clear the clock bits */ 198 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 199 - reg &= ~0xf; 200 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 201 - } /* synth_chip_init */ 202 - 203 - 204 - static void antenna_init(struct agnx_priv *priv, int num_antenna) 205 - { 206 - void __iomem *ctl = priv->ctl; 207 - 208 - switch (num_antenna) { 209 - case 1: 210 - agnx_write32(ctl, AGNX_GCR_NLISTANT, 1); 211 - agnx_write32(ctl, AGNX_GCR_NMEASANT, 1); 212 - agnx_write32(ctl, AGNX_GCR_NACTIANT, 1); 213 - agnx_write32(ctl, AGNX_GCR_NCAPTANT, 1); 214 - 215 - agnx_write32(ctl, AGNX_GCR_ANTCFG, 7); 216 - agnx_write32(ctl, AGNX_GCR_BOACT, 34); 217 - agnx_write32(ctl, AGNX_GCR_BOINACT, 34); 218 - agnx_write32(ctl, AGNX_GCR_BODYNA, 30); 219 - 220 - agnx_write32(ctl, AGNX_GCR_THD0A, 125); 221 - agnx_write32(ctl, AGNX_GCR_THD0AL, 100); 222 - agnx_write32(ctl, AGNX_GCR_THD0B, 90); 223 - 224 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 80); 225 - agnx_write32(ctl, AGNX_GCR_SIGHTH, 100); 226 - agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); 227 - break; 228 - case 2: 229 - agnx_write32(ctl, AGNX_GCR_NLISTANT, 2); 230 - agnx_write32(ctl, AGNX_GCR_NMEASANT, 2); 231 - agnx_write32(ctl, AGNX_GCR_NACTIANT, 2); 232 - agnx_write32(ctl, AGNX_GCR_NCAPTANT, 2); 233 - agnx_write32(ctl, AGNX_GCR_ANTCFG, 15); 234 - agnx_write32(ctl, AGNX_GCR_BOACT, 36); 235 - agnx_write32(ctl, AGNX_GCR_BOINACT, 36); 236 - agnx_write32(ctl, AGNX_GCR_BODYNA, 32); 237 - agnx_write32(ctl, AGNX_GCR_THD0A, 120); 238 - agnx_write32(ctl, AGNX_GCR_THD0AL, 100); 239 - agnx_write32(ctl, AGNX_GCR_THD0B, 80); 240 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70); 241 - agnx_write32(ctl, AGNX_GCR_SIGHTH, 100); 242 - agnx_write32(ctl, AGNX_GCR_SIGLTH, 32); 243 - break; 244 - case 3: 245 - agnx_write32(ctl, AGNX_GCR_NLISTANT, 3); 246 - agnx_write32(ctl, AGNX_GCR_NMEASANT, 3); 247 - agnx_write32(ctl, AGNX_GCR_NACTIANT, 3); 248 - agnx_write32(ctl, AGNX_GCR_NCAPTANT, 3); 249 - agnx_write32(ctl, AGNX_GCR_ANTCFG, 31); 250 - agnx_write32(ctl, AGNX_GCR_BOACT, 36); 251 - agnx_write32(ctl, AGNX_GCR_BOINACT, 36); 252 - agnx_write32(ctl, AGNX_GCR_BODYNA, 32); 253 - agnx_write32(ctl, AGNX_GCR_THD0A, 100); 254 - agnx_write32(ctl, AGNX_GCR_THD0AL, 100); 255 - agnx_write32(ctl, AGNX_GCR_THD0B, 70); 256 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70); 257 - agnx_write32(ctl, AGNX_GCR_SIGHTH, 100); 258 - agnx_write32(ctl, AGNX_GCR_SIGLTH, 48); 259 - /* agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */ 260 - break; 261 - default: 262 - printk(KERN_WARNING PFX "Unknow antenna number\n"); 263 - } 264 - } /* antenna_init */ 265 - 266 - static void chain_update(struct agnx_priv *priv, u32 chain) 267 - { 268 - void __iomem *ctl = priv->ctl; 269 - u32 reg; 270 - AGNX_TRACE; 271 - 272 - spi_rc_write(ctl, RF_CHIP0, 0x20); 273 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 274 - 275 - if (reg == 0x4) 276 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000); 277 - else if (reg != 0x0) 278 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000); 279 - else { 280 - if (chain == 3 || chain == 6) { 281 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000); 282 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 283 - } else if (chain == 2 || chain == 4) { 284 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000); 285 - spi_rf_write(ctl, RF_CHIP2, 0x1005); 286 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x824); 287 - } else if (chain == 1) { 288 - spi_rf_write(ctl, RF_CHIP0, reg|0x1000); 289 - spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1004); 290 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xc36); 291 - } 292 - } 293 - 294 - spi_rc_write(ctl, RF_CHIP0, 0x22); 295 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 296 - 297 - switch (reg) { 298 - case 0: 299 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005); 300 - break; 301 - case 1: 302 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 303 - break; 304 - case 2: 305 - if (chain == 6 || chain == 4) { 306 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1202); 307 - spi_rf_write(ctl, RF_CHIP2, 0x1005); 308 - } else if (chain < 3) { 309 - spi_rf_write(ctl, RF_CHIP0, 0x1202); 310 - spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1005); 311 - } 312 - break; 313 - default: 314 - if (chain == 3) { 315 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203); 316 - spi_rf_write(ctl, RF_CHIP2, 0x1201); 317 - } else if (chain == 2) { 318 - spi_rf_write(ctl, RF_CHIP0, 0x1203); 319 - spi_rf_write(ctl, RF_CHIP2, 0x1200); 320 - spi_rf_write(ctl, RF_CHIP1, 0x1201); 321 - } else if (chain == 1) { 322 - spi_rf_write(ctl, RF_CHIP0, 0x1203); 323 - spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1200); 324 - } else if (chain == 4) { 325 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203); 326 - spi_rf_write(ctl, RF_CHIP2, 0x1201); 327 - } else { 328 - spi_rf_write(ctl, RF_CHIP0, 0x1203); 329 - spi_rf_write(ctl, RF_CHIP1|RF_CHIP2, 0x1201); 330 - } 331 - } 332 - } /* chain_update */ 333 - 334 - static void antenna_config(struct agnx_priv *priv) 335 - { 336 - void __iomem *ctl = priv->ctl; 337 - u32 reg; 338 - AGNX_TRACE; 339 - 340 - /* Write 0x0 to the TX Management Control Register Enable bit */ 341 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 342 - reg &= ~0x1; 343 - agnx_write32(ctl, AGNX_TXM_CTL, reg); 344 - 345 - /* FIXME */ 346 - /* Set initial value based on number of Antennae */ 347 - antenna_init(priv, 3); 348 - 349 - /* FIXME Update Power Templates for current valid Stations */ 350 - /* sta_power_init(priv, 0);*/ 351 - 352 - /* FIXME the number of chains should get from eeprom*/ 353 - chain_update(priv, AGNX_CHAINS_MAX); 354 - } /* antenna_config */ 355 - 356 - void calibrate_oscillator(struct agnx_priv *priv) 357 - { 358 - void __iomem *ctl = priv->ctl; 359 - u32 reg; 360 - AGNX_TRACE; 361 - 362 - spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 363 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET1); 364 - reg |= 0x10; 365 - agnx_write32(ctl, AGNX_GCR_GAINSET1, reg); 366 - 367 - agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 1); 368 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 1); 369 - 370 - agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff); 371 - 372 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27); 373 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 374 - /* (Residual DC Calibration) to Calibration Mode */ 375 - agnx_write32(ctl, AGNX_ACI_MODE, 0x2); 376 - 377 - spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x1004); 378 - agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff); 379 - /* (TX LO Calibration) to Calibration Mode */ 380 - agnx_write32(ctl, AGNX_ACI_MODE, 0x4); 381 - 382 - do { 383 - u32 reg1, reg2, reg3; 384 - /* Enable Power Saving Control */ 385 - enable_power_saving(priv); 386 - /* Save the following registers to restore */ 387 - reg1 = ioread32(ctl + 0x11000); 388 - reg2 = ioread32(ctl + 0xec50); 389 - reg3 = ioread32(ctl + 0xec54); 390 - wmb(); 391 - 392 - agnx_write32(ctl, 0x11000, 0xcfdf); 393 - agnx_write32(ctl, 0xec50, 0x70); 394 - /* Restore the registers */ 395 - agnx_write32(ctl, 0x11000, reg1); 396 - agnx_write32(ctl, 0xec50, reg2); 397 - agnx_write32(ctl, 0xec54, reg3); 398 - /* Disable Power Saving Control */ 399 - disable_power_saving(priv); 400 - } while (0); 401 - 402 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0); 403 - } /* calibrate_oscillator */ 404 - 405 - 406 - static void radio_channel_set(struct agnx_priv *priv, unsigned int channel) 407 - { 408 - void __iomem *ctl = priv->ctl; 409 - unsigned int freq = priv->band.channels[channel - 1].center_freq; 410 - u32 reg; 411 - AGNX_TRACE; 412 - 413 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 414 - /* Set SPI Clock to 50 Ns */ 415 - reg = agnx_read32(ctl, AGNX_SPI_CFG); 416 - reg &= ~0xF; 417 - reg |= 0x1; 418 - agnx_write32(ctl, AGNX_SPI_CFG, reg); 419 - 420 - /* Clear the Disable Tx interrupt bit in Interrupt Mask */ 421 - /* reg = agnx_read32(ctl, AGNX_INT_MASK); */ 422 - /* reg &= ~IRQ_TX_DISABLE; */ 423 - /* agnx_write32(ctl, AGNX_INT_MASK, reg); */ 424 - 425 - /* Band Selection */ 426 - reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT); 427 - reg |= 0x8; 428 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg); 429 - 430 - /* FIXME Set the SiLabs Chip Frequency */ 431 - synth_freq_set(priv, channel); 432 - 433 - reg = agnx_read32(ctl, AGNX_PM_SOFTRST); 434 - reg |= 0x80100030; 435 - agnx_write32(ctl, AGNX_PM_SOFTRST, reg); 436 - reg = agnx_read32(ctl, AGNX_PM_PLLCTL); 437 - reg |= 0x20009; 438 - agnx_write32(ctl, AGNX_PM_PLLCTL, reg); 439 - 440 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, 0x5); 441 - 442 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1100); 443 - 444 - /* Load the MonitorGain Table */ 445 - monitor_gain_table_init(priv); 446 - 447 - /* Load the TX Fir table */ 448 - tx_fir_table_init(priv); 449 - 450 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 451 - reg |= 0x8; 452 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 453 - 454 - spi_rc_write(ctl, RF_CHIP0|RF_CHIP1, 0x22); 455 - udelay(80); 456 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 457 - 458 - 459 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff); 460 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 461 - 462 - reg = agnx_read32(ctl, 0xec50); 463 - reg |= 0x4f; 464 - agnx_write32(ctl, 0xec50, reg); 465 - 466 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 467 - agnx_write32(ctl, 0x11008, 0x1); 468 - agnx_write32(ctl, 0x1100c, 0x0); 469 - agnx_write32(ctl, 0x11008, 0x0); 470 - agnx_write32(ctl, 0xec50, 0xc); 471 - 472 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 473 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 474 - agnx_write32(ctl, 0x11010, 0x6e); 475 - agnx_write32(ctl, 0x11014, 0x6c); 476 - 477 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1201); 478 - 479 - /* Calibrate the Antenna */ 480 - /* antenna_calibrate(priv); */ 481 - /* Calibrate the TxLocalOscillator */ 482 - calibrate_oscillator(priv); 483 - 484 - reg = agnx_read32(ctl, AGNX_PM_PMCTL); 485 - reg &= ~0x8; 486 - agnx_write32(ctl, AGNX_PM_PMCTL, reg); 487 - agnx_write32(ctl, AGNX_GCR_GAININIT, 0xa); 488 - agnx_write32(ctl, AGNX_GCR_THCD, 0x0); 489 - 490 - agnx_write32(ctl, 0x11018, 0xb); 491 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x0); 492 - 493 - /* Write Frequency to Gain Control Channel */ 494 - agnx_write32(ctl, AGNX_GCR_RXCHANEL, freq); 495 - /* Write 0x140000/Freq to 0x9c08 */ 496 - reg = 0x140000/freq; 497 - agnx_write32(ctl, 0x9c08, reg); 498 - 499 - reg = agnx_read32(ctl, AGNX_PM_SOFTRST); 500 - reg &= ~0x80100030; 501 - agnx_write32(ctl, AGNX_PM_SOFTRST, reg); 502 - 503 - reg = agnx_read32(ctl, AGNX_PM_PLLCTL); 504 - reg &= ~0x20009; 505 - reg |= 0x1; 506 - agnx_write32(ctl, AGNX_PM_PLLCTL, reg); 507 - 508 - agnx_write32(ctl, AGNX_ACI_MODE, 0x0); 509 - 510 - /* FIXME According to Number of Chains: */ 511 - 512 - /* 1. 1: */ 513 - /* 1. Write 0x1203 to RF Chip 0 */ 514 - /* 2. Write 0x1200 to RF Chips 1 +2 */ 515 - /* 2. 2: */ 516 - /* 1. Write 0x1203 to RF Chip 0 */ 517 - /* 2. Write 0x1200 to RF Chip 2 */ 518 - /* 3. Write 0x1201 to RF Chip 1 */ 519 - /* 3. 3: */ 520 - /* 1. Write 0x1203 to RF Chip 0 */ 521 - /* 2. Write 0x1201 to RF Chip 1 + 2 */ 522 - /* 4. 4: */ 523 - /* 1. Write 0x1203 to RF Chip 0 + 1 */ 524 - /* 2. Write 0x1200 to RF Chip 2 */ 525 - 526 - /* 5. 6: */ 527 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, 0x1203); 528 - spi_rf_write(ctl, RF_CHIP2, 0x1201); 529 - 530 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000); 531 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 532 - 533 - /* FIXME Set the Disable Tx interrupt bit in Interrupt Mask 534 - (Or 0x20000 to Interrupt Mask) */ 535 - /* reg = agnx_read32(ctl, AGNX_INT_MASK); */ 536 - /* reg |= IRQ_TX_DISABLE; */ 537 - /* agnx_write32(ctl, AGNX_INT_MASK, reg); */ 538 - 539 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1); 540 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0); 541 - 542 - /* Configure the Antenna */ 543 - antenna_config(priv); 544 - 545 - /* Write 0x0 to Discovery Mode Enable detect G, B, A packet? */ 546 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0); 547 - 548 - reg = agnx_read32(ctl, AGNX_RXM_REQRATE); 549 - reg |= 0x80000000; 550 - agnx_write32(ctl, AGNX_RXM_REQRATE, reg); 551 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1); 552 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0); 553 - 554 - /* enable radio on and the power LED */ 555 - reg = agnx_read32(ctl, AGNX_SYSITF_GPIOUT); 556 - reg &= ~0x1; 557 - reg |= 0x2; 558 - agnx_write32(ctl, AGNX_SYSITF_GPIOUT, reg); 559 - 560 - reg = agnx_read32(ctl, AGNX_TXM_CTL); 561 - reg |= 0x1; 562 - agnx_write32(ctl, AGNX_TXM_CTL, reg); 563 - } /* radio_channel_set */ 564 - 565 - static void base_band_filter_calibrate(struct agnx_priv *priv) 566 - { 567 - void __iomem *ctl = priv->ctl; 568 - 569 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700); 570 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1001); 571 - agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x0); 572 - spi_rc_write(ctl, RF_CHIP0, 0x27); 573 - spi_rc_write(ctl, RF_CHIP1, 0x27); 574 - spi_rc_write(ctl, RF_CHIP2, 0x27); 575 - agnx_write32(ctl, AGNX_GCR_FORCECTLCLK, 0x1); 576 - } 577 - 578 - static void print_offset(struct agnx_priv *priv, u32 chain) 579 - { 580 - void __iomem *ctl = priv->ctl; 581 - u32 offset; 582 - 583 - iowrite32((chain), ctl + AGNX_ACI_SELCHAIN); 584 - udelay(10); 585 - offset = (ioread32(ctl + AGNX_ACI_OFFSET)); 586 - printk(PFX "Chain is 0x%x, Offset is 0x%x\n", chain, offset); 587 - } 588 - 589 - void print_offsets(struct agnx_priv *priv) 590 - { 591 - print_offset(priv, 0); 592 - print_offset(priv, 4); 593 - print_offset(priv, 1); 594 - print_offset(priv, 5); 595 - print_offset(priv, 2); 596 - print_offset(priv, 6); 597 - } 598 - 599 - 600 - struct chains { 601 - u32 cali; /* calibrate value*/ 602 - 603 - #define NEED_CALIBRATE 0 604 - #define SUCCESS_CALIBRATE 1 605 - int status; 606 - }; 607 - 608 - static void chain_calibrate(struct agnx_priv *priv, struct chains *chains, 609 - unsigned int num) 610 - { 611 - void __iomem *ctl = priv->ctl; 612 - u32 calibra = chains[num].cali; 613 - 614 - if (num < 3) 615 - calibra |= 0x1400; 616 - else 617 - calibra |= 0x1500; 618 - 619 - switch (num) { 620 - case 0: 621 - case 4: 622 - spi_rf_write(ctl, RF_CHIP0, calibra); 623 - break; 624 - case 1: 625 - case 5: 626 - spi_rf_write(ctl, RF_CHIP1, calibra); 627 - break; 628 - case 2: 629 - case 6: 630 - spi_rf_write(ctl, RF_CHIP2, calibra); 631 - break; 632 - default: 633 - BUG(); 634 - } 635 - } /* chain_calibrate */ 636 - 637 - static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains, 638 - unsigned int num) 639 - { 640 - void __iomem *ctl = priv->ctl; 641 - u32 offset; 642 - 643 - iowrite32((num), ctl + AGNX_ACI_SELCHAIN); 644 - /* FIXME */ 645 - udelay(10); 646 - offset = (ioread32(ctl + AGNX_ACI_OFFSET)); 647 - 648 - if (offset < 0xf) { 649 - chains[num].status = SUCCESS_CALIBRATE; 650 - return; 651 - } 652 - 653 - if (num == 0 || num == 1 || num == 2) { 654 - if (0 == chains[num].cali) 655 - chains[num].cali = 0xff; 656 - else 657 - chains[num].cali--; 658 - } else 659 - chains[num].cali++; 660 - 661 - chains[num].status = NEED_CALIBRATE; 662 - } 663 - 664 - static inline void calibra_delay(struct agnx_priv *priv) 665 - { 666 - void __iomem *ctl = priv->ctl; 667 - u32 reg; 668 - unsigned int i = 100; 669 - 670 - wmb(); 671 - while (--i) { 672 - reg = (ioread32(ctl + AGNX_ACI_STATUS)); 673 - if (reg == 0x4000) 674 - break; 675 - udelay(10); 676 - } 677 - if (!i) 678 - printk(PFX "calibration failed\n"); 679 - } 680 - 681 - void do_calibration(struct agnx_priv *priv) 682 - { 683 - void __iomem *ctl = priv->ctl; 684 - struct chains chains[7]; 685 - unsigned int i, j; 686 - AGNX_TRACE; 687 - 688 - for (i = 0; i < 7; i++) { 689 - if (i == 3) 690 - continue; 691 - 692 - chains[i].cali = 0x7f; 693 - chains[i].status = NEED_CALIBRATE; 694 - } 695 - 696 - /* FIXME 0x300 is a magic number */ 697 - for (j = 0; j < 0x300; j++) { 698 - if (chains[0].status == SUCCESS_CALIBRATE && 699 - chains[1].status == SUCCESS_CALIBRATE && 700 - chains[2].status == SUCCESS_CALIBRATE && 701 - chains[4].status == SUCCESS_CALIBRATE && 702 - chains[5].status == SUCCESS_CALIBRATE && 703 - chains[6].status == SUCCESS_CALIBRATE) 704 - break; 705 - 706 - /* Attention, there is no chain 3 */ 707 - for (i = 0; i < 7; i++) { 708 - if (i == 3) 709 - continue; 710 - if (chains[i].status == NEED_CALIBRATE) 711 - chain_calibrate(priv, chains, i); 712 - } 713 - /* Write 0x1 to Calibration Measure */ 714 - iowrite32((0x1), ctl + AGNX_ACI_MEASURE); 715 - calibra_delay(priv); 716 - 717 - for (i = 0; i < 7; i++) { 718 - if (i == 3) 719 - continue; 720 - 721 - get_calibrete_value(priv, chains, i); 722 - } 723 - } 724 - printk(PFX "Clibrate times is %d\n", j); 725 - print_offsets(priv); 726 - } /* do_calibration */ 727 - 728 - void antenna_calibrate(struct agnx_priv *priv) 729 - { 730 - void __iomem *ctl = priv->ctl; 731 - u32 reg; 732 - AGNX_TRACE; 733 - 734 - agnx_write32(ctl, AGNX_GCR_NLISTANT, 0x3); 735 - agnx_write32(ctl, AGNX_GCR_NMEASANT, 0x3); 736 - agnx_write32(ctl, AGNX_GCR_NACTIANT, 0x3); 737 - agnx_write32(ctl, AGNX_GCR_NCAPTANT, 0x3); 738 - 739 - agnx_write32(ctl, AGNX_GCR_ANTCFG, 0x1f); 740 - agnx_write32(ctl, AGNX_GCR_BOACT, 0x24); 741 - agnx_write32(ctl, AGNX_GCR_BOINACT, 0x24); 742 - agnx_write32(ctl, AGNX_GCR_BODYNA, 0x20); 743 - agnx_write32(ctl, AGNX_GCR_THD0A, 0x64); 744 - agnx_write32(ctl, AGNX_GCR_THD0AL, 0x64); 745 - agnx_write32(ctl, AGNX_GCR_THD0B, 0x46); 746 - agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 0x3c); 747 - agnx_write32(ctl, AGNX_GCR_SIGHTH, 0x64); 748 - agnx_write32(ctl, AGNX_GCR_SIGLTH, 0x30); 749 - 750 - spi_rc_write(ctl, RF_CHIP0, 0x20); 751 - /* Fixme */ 752 - udelay(80); 753 - /* 1. Should read 0x0 */ 754 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 755 - if (0x0 != reg) 756 - printk(KERN_WARNING PFX "Unmatched rf chips result\n"); 757 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1000); 758 - 759 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 760 - 761 - spi_rc_write(ctl, RF_CHIP0, 0x22); 762 - udelay(80); 763 - reg = agnx_read32(ctl, AGNX_SPI_RLSW); 764 - if (0x0 != reg) 765 - printk(KERN_WARNING PFX "Unmatched rf chips result\n"); 766 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1005); 767 - 768 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x1); 769 - agnx_write32(ctl, AGNX_GCR_RSTGCTL, 0x0); 770 - 771 - reg = agnx_read32(ctl, AGNX_PM_SOFTRST); 772 - reg |= 0x1c000032; 773 - agnx_write32(ctl, AGNX_PM_SOFTRST, reg); 774 - reg = agnx_read32(ctl, AGNX_PM_PLLCTL); 775 - reg |= 0x0003f07; 776 - agnx_write32(ctl, AGNX_PM_PLLCTL, reg); 777 - 778 - reg = agnx_read32(ctl, 0xec50); 779 - reg |= 0x40; 780 - agnx_write32(ctl, 0xec50, reg); 781 - 782 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0xff8); 783 - agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3); 784 - 785 - agnx_write32(ctl, AGNX_GCR_CHAINNUM, 0x6); 786 - agnx_write32(ctl, 0x19874, 0x0); 787 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1700); 788 - 789 - /* Calibrate the BaseBandFilter */ 790 - base_band_filter_calibrate(priv); 791 - 792 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002); 793 - 794 - agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d); 795 - agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d); 796 - agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d); 797 - agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1); 798 - 799 - agnx_write32(ctl, AGNX_ACI_MODE, 0x1); 800 - agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff); 801 - 802 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27); 803 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 804 - 805 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400); 806 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500); 807 - 808 - /* Measure Calibration */ 809 - agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1); 810 - calibra_delay(priv); 811 - 812 - /* do calibration */ 813 - do_calibration(priv); 814 - 815 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 816 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21); 817 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 818 - agnx_write32(ctl, AGNX_ACI_LEN, 0xf); 819 - 820 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET0); 821 - reg &= 0xf; 822 - agnx_write32(ctl, AGNX_GCR_GAINSET0, reg); 823 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET1); 824 - reg &= 0xf; 825 - agnx_write32(ctl, AGNX_GCR_GAINSET1, reg); 826 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET2); 827 - reg &= 0xf; 828 - agnx_write32(ctl, AGNX_GCR_GAINSET2, reg); 829 - 830 - agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0); 831 - disable_receiver(priv); 832 - } /* antenna_calibrate */ 833 - 834 - void __antenna_calibrate(struct agnx_priv *priv) 835 - { 836 - void __iomem *ctl = priv->ctl; 837 - u32 reg; 838 - 839 - /* Calibrate the BaseBandFilter */ 840 - /* base_band_filter_calibrate(priv); */ 841 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1002); 842 - 843 - 844 - agnx_write32(ctl, AGNX_GCR_GAINSET0, 0x1d); 845 - agnx_write32(ctl, AGNX_GCR_GAINSET1, 0x1d); 846 - agnx_write32(ctl, AGNX_GCR_GAINSET2, 0x1d); 847 - 848 - agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x1); 849 - 850 - agnx_write32(ctl, AGNX_ACI_MODE, 0x1); 851 - agnx_write32(ctl, AGNX_ACI_LEN, 0x3ff); 852 - 853 - 854 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x27); 855 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 856 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1400); 857 - spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, 0x1500); 858 - /* Measure Calibration */ 859 - agnx_write32(ctl, AGNX_ACI_MEASURE, 0x1); 860 - calibra_delay(priv); 861 - do_calibration(priv); 862 - agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0); 863 - 864 - agnx_write32(ctl, AGNX_ACI_TIMER1, 0x21); 865 - agnx_write32(ctl, AGNX_ACI_TIMER2, 0x27); 866 - 867 - agnx_write32(ctl, AGNX_ACI_LEN, 0xf); 868 - 869 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET0); 870 - reg &= 0xf; 871 - agnx_write32(ctl, AGNX_GCR_GAINSET0, reg); 872 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET1); 873 - reg &= 0xf; 874 - agnx_write32(ctl, AGNX_GCR_GAINSET1, reg); 875 - reg = agnx_read32(ctl, AGNX_GCR_GAINSET2); 876 - reg &= 0xf; 877 - agnx_write32(ctl, AGNX_GCR_GAINSET2, reg); 878 - 879 - 880 - agnx_write32(ctl, AGNX_GCR_GAINSETWRITE, 0x0); 881 - 882 - /* Write 0x3 Gain Control Discovery Mode */ 883 - enable_receiver(priv); 884 - } 885 - 886 - int agnx_set_channel(struct agnx_priv *priv, unsigned int channel) 887 - { 888 - AGNX_TRACE; 889 - 890 - printk(KERN_ERR PFX "Channel is %d %s\n", channel, __func__); 891 - radio_channel_set(priv, channel); 892 - return 0; 893 - }
-218
drivers/staging/agnx/sta.c
··· 1 - #include <linux/delay.h> 2 - #include <linux/etherdevice.h> 3 - #include "phy.h" 4 - #include "sta.h" 5 - #include "debug.h" 6 - 7 - void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id) 8 - { 9 - void __iomem *ctl = priv->ctl; 10 - 11 - reglo &= 0xFFFF; 12 - reglo |= 0x30000000; 13 - reglo |= 0x40000000; /* Set status busy */ 14 - reglo |= sta_id << 16; 15 - 16 - iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG); 17 - iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH); 18 - iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW); 19 - 20 - reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH); 21 - reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW); 22 - printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo); 23 - } 24 - 25 - void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id) 26 - { 27 - void __iomem *ctl = priv->ctl; 28 - u32 reghi, reglo; 29 - 30 - if (!is_valid_ether_addr(mac_addr)) 31 - printk(KERN_WARNING PFX "Update hash table: Invalid hwaddr!\n"); 32 - 33 - reghi = mac_addr[0] << 24 | mac_addr[1] << 16 | mac_addr[2] << 8 | mac_addr[3]; 34 - reglo = mac_addr[4] << 8 | mac_addr[5]; 35 - reglo |= 0x10000000; /* Set hash commmand */ 36 - reglo |= 0x40000000; /* Set status busy */ 37 - reglo |= sta_id << 16; 38 - 39 - iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG); 40 - iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH); 41 - iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW); 42 - 43 - reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW); 44 - if (!(reglo & 0x80000000)) 45 - printk(KERN_WARNING PFX "Update hash table failed\n"); 46 - } 47 - 48 - void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id) 49 - { 50 - void __iomem *ctl = priv->ctl; 51 - 52 - reglo &= 0xFFFF; 53 - reglo |= 0x20000000; 54 - reglo |= 0x40000000; /* Set status busy */ 55 - reglo |= sta_id << 16; 56 - 57 - iowrite32(0, ctl + AGNX_RXM_HASH_CMD_FLAG); 58 - iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH); 59 - iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW); 60 - reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH); 61 - 62 - reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW); 63 - printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo); 64 - 65 - } 66 - 67 - void hash_dump(struct agnx_priv *priv, u8 sta_id) 68 - { 69 - void __iomem *ctl = priv->ctl; 70 - u32 reghi, reglo; 71 - 72 - reglo = 0x40000000; /* status bit */ 73 - iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW); 74 - iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA); 75 - 76 - udelay(80); 77 - 78 - reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH); 79 - reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW); 80 - printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo); 81 - reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG); 82 - printk(PFX "hash flag is : %.8x\n", reghi); 83 - reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_MST); 84 - reglo = ioread32(ctl + AGNX_RXM_HASH_DUMP_LST); 85 - printk(PFX "hash dump mst lst: %.8x%.8x\n", reghi, reglo); 86 - reghi = ioread32(ctl + AGNX_RXM_HASH_DUMP_DATA); 87 - printk(PFX "hash dump data: %.8x\n", reghi); 88 - } 89 - 90 - void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx) 91 - { 92 - void __iomem *ctl = priv->ctl; 93 - memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx, 94 - sizeof(*power)); 95 - } 96 - 97 - inline void 98 - set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx) 99 - { 100 - void __iomem *ctl = priv->ctl; 101 - /* FIXME 2. Write Template to offset + station number */ 102 - memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx, 103 - power, sizeof(*power)); 104 - } 105 - 106 - 107 - void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq, 108 - unsigned int sta_idx, unsigned int wq_idx) 109 - { 110 - void __iomem *data = priv->data; 111 - memcpy_fromio(tx_wq, data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx + 112 - sizeof(*tx_wq) * wq_idx, sizeof(*tx_wq)); 113 - 114 - } 115 - 116 - inline void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq, 117 - unsigned int sta_idx, unsigned int wq_idx) 118 - { 119 - void __iomem *data = priv->data; 120 - memcpy_toio(data + AGNX_PDU_TX_WQ + sizeof(*tx_wq) * STA_TX_WQ_NUM * sta_idx + 121 - sizeof(*tx_wq) * wq_idx, tx_wq, sizeof(*tx_wq)); 122 - } 123 - 124 - 125 - void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx) 126 - { 127 - void __iomem *data = priv->data; 128 - 129 - memcpy_fromio(sta, data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx, 130 - sizeof(*sta)); 131 - } 132 - 133 - inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx) 134 - { 135 - void __iomem *data = priv->data; 136 - 137 - memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx, 138 - sta, sizeof(*sta)); 139 - } 140 - 141 - /* FIXME */ 142 - void sta_power_init(struct agnx_priv *priv, unsigned int sta_idx) 143 - { 144 - struct agnx_sta_power power; 145 - u32 reg; 146 - AGNX_TRACE; 147 - 148 - memset(&power, 0, sizeof(power)); 149 - reg = agnx_set_bits(EDCF, EDCF_SHIFT, 0x1); 150 - power.reg = cpu_to_le32(reg); 151 - set_sta_power(priv, &power, sta_idx); 152 - udelay(40); 153 - } /* add_power_template */ 154 - 155 - 156 - /* @num: The #number of station that is visible to the card */ 157 - static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx) 158 - { 159 - struct agnx_sta_tx_wq tx_wq; 160 - u32 reg; 161 - unsigned int i; 162 - 163 - memset(&tx_wq, 0, sizeof(tx_wq)); 164 - 165 - reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1); 166 - reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1); 167 - /* reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */ 168 - tx_wq.reg2 |= cpu_to_le32(reg); 169 - 170 - /* Suppose all 8 traffic class are used */ 171 - for (i = 0; i < STA_TX_WQ_NUM; i++) 172 - set_sta_tx_wq(priv, &tx_wq, sta_idx, i); 173 - } /* sta_tx_workqueue_init */ 174 - 175 - 176 - static void sta_traffic_init(struct agnx_sta_traffic *traffic) 177 - { 178 - u32 reg; 179 - memset(traffic, 0, sizeof(*traffic)); 180 - 181 - reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1); 182 - reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1); 183 - /* reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */ 184 - traffic->reg0 = cpu_to_le32(reg); 185 - 186 - /* 3. setting RX Sequence Number to 4095 */ 187 - reg = agnx_set_bits(RX_SEQUENCE_NUM, RX_SEQUENCE_NUM_SHIFT, 4095); 188 - traffic->reg1 = cpu_to_le32(reg); 189 - } 190 - 191 - 192 - /* @num: The #number of station that is visible to the card */ 193 - void sta_init(struct agnx_priv *priv, unsigned int sta_idx) 194 - { 195 - /* FIXME the length of sta is 256 bytes Is that 196 - * dangerous to stack overflow? */ 197 - struct agnx_sta sta; 198 - u32 reg; 199 - int i; 200 - 201 - memset(&sta, 0, sizeof(sta)); 202 - /* Set valid to 1 */ 203 - reg = agnx_set_bits(STATION_VALID, STATION_VALID_SHIFT, 1); 204 - /* Set Enable Concatenation to 0 (?) */ 205 - reg |= agnx_set_bits(ENABLE_CONCATENATION, ENABLE_CONCATENATION_SHIFT, 0); 206 - /* Set Enable Decompression to 0 (?) */ 207 - reg |= agnx_set_bits(ENABLE_DECOMPRESSION, ENABLE_DECOMPRESSION_SHIFT, 0); 208 - sta.reg = cpu_to_le32(reg); 209 - 210 - /* Initialize each of the Traffic Class Structures by: */ 211 - for (i = 0; i < 8; i++) 212 - sta_traffic_init(sta.traffic + i); 213 - 214 - set_sta(priv, &sta, sta_idx); 215 - sta_tx_workqueue_init(priv, sta_idx); 216 - } /* sta_descriptor_init */ 217 - 218 -
-222
drivers/staging/agnx/sta.h
··· 1 - #ifndef AGNX_STA_H_ 2 - #define AGNX_STA_H_ 3 - 4 - #define STA_TX_WQ_NUM 8 /* The number of TX workqueue one STA has */ 5 - 6 - struct agnx_hash_cmd { 7 - __be32 cmdhi; 8 - #define MACLO 0xFFFF0000 9 - #define MACLO_SHIFT 16 10 - #define STA_ID 0x0000FFF0 11 - #define STA_ID_SHIFT 4 12 - #define CMD 0x0000000C 13 - #define CMD_SHIFT 2 14 - #define STATUS 0x00000002 15 - #define STATUS_SHIFT 1 16 - #define PASS 0x00000001 17 - #define PASS_SHIFT 1 18 - __be32 cmdlo; 19 - } __attribute__((__packed__)); 20 - 21 - 22 - /* 23 - * Station Power Template 24 - * FIXME Just for agn100 yet 25 - */ 26 - struct agnx_sta_power { 27 - __le32 reg; 28 - #define SIGNAL 0x000000FF /* signal */ 29 - #define SIGNAL_SHIFT 0 30 - #define RATE 0x00000F00 31 - #define RATE_SHIFT 8 32 - #define TIFS 0x00001000 33 - #define TIFS_SHIFT 12 34 - #define EDCF 0x00002000 35 - #define EDCF_SHIFT 13 36 - #define CHANNEL_BOND 0x00004000 37 - #define CHANNEL_BOND_SHIFT 14 38 - #define PHY_MODE 0x00038000 39 - #define PHY_MODE_SHIFT 15 40 - #define POWER_LEVEL 0x007C0000 41 - #define POWER_LEVEL_SHIFT 18 42 - #define NUM_TRANSMITTERS 0x00800000 43 - #define NUM_TRANSMITTERS_SHIFT 23 44 - } __attribute__((__packed__)); 45 - 46 - /* 47 - * TX Workqueue Descriptor 48 - */ 49 - struct agnx_sta_tx_wq { 50 - __le32 reg0; 51 - #define HEAD_POINTER_LOW 0xFF000000 /* Head pointer low */ 52 - #define HEAD_POINTER_LOW_SHIFT 24 53 - #define TAIL_POINTER 0x00FFFFFF /* Tail pointer */ 54 - #define TAIL_POINTER_SHIFT 0 55 - 56 - __le32 reg3; 57 - #define ACK_POINTER_LOW 0xFFFF0000 /* ACK pointer low */ 58 - #define ACK_POINTER_LOW_SHIFT 16 59 - #define HEAD_POINTER_HIGH 0x0000FFFF /* Head pointer high */ 60 - #define HEAD_POINTER_HIGH_SHIFT 0 61 - 62 - __le32 reg1; 63 - /* ACK timeout tail packet count */ 64 - #define ACK_TIMOUT_TAIL_PACK_CNT 0xFFF00000 65 - #define ACK_TIMOUT_TAIL_PACK_CNT_SHIFT 20 66 - /* Head timeout tail packet count */ 67 - #define HEAD_TIMOUT_TAIL_PACK_CNT 0x000FFF00 68 - #define HEAD_TIMOUT_TAIL_PACK_CNT_SHIFT 8 69 - #define ACK_POINTER_HIGH 0x000000FF /* ACK pointer high */ 70 - #define ACK_POINTER_HIGH_SHIFT 0 71 - 72 - __le32 reg2; 73 - #define WORK_QUEUE_VALID 0x80000000 /* valid */ 74 - #define WORK_QUEUE_VALID_SHIFT 31 75 - #define WORK_QUEUE_ACK_TYPE 0x40000000 /* ACK type */ 76 - #define WORK_QUEUE_ACK_TYPE_SHIFT 30 77 - /* Head timeout window limit fragmentation count */ 78 - #define HEAD_TIMOUT_WIN_LIM_FRAG_CNT 0x3FFF0000 79 - #define HEAD_TIMOUT_WIN_LIM_FRAG_CNT_SHIFT 16 80 - /* Head timeout window limit byte count */ 81 - #define HEAD_TIMOUT_WIN_LIM_BYTE_CNT 0x0000FFFF 82 - #define HEAD_TIMOUT_WIN_LIM_BYTE_CNT_SHIFT 0 83 - } __attribute__((__packed__)); 84 - 85 - 86 - /* 87 - * Traffic Class Structure 88 - */ 89 - struct agnx_sta_traffic { 90 - __le32 reg0; 91 - #define ACK_TIMOUT_CNT 0xFF800000 /* ACK Timeout Counts */ 92 - #define ACK_TIMOUT_CNT_SHIFT 23 93 - #define TRAFFIC_ACK_TYPE 0x00600000 /* ACK Type */ 94 - #define TRAFFIC_ACK_TYPE_SHIFT 21 95 - #define NEW_PACKET 0x00100000 /* New Packet */ 96 - #define NEW_PACKET_SHIFT 20 97 - #define TRAFFIC_VALID 0x00080000 /* Valid */ 98 - #define TRAFFIC_VALID_SHIFT 19 99 - #define RX_HDR_DESC_POINTER 0x0007FFFF /* RX Header Descripter pointer */ 100 - #define RX_HDR_DESC_POINTER_SHIFT 0 101 - 102 - __le32 reg1; 103 - #define RX_PACKET_TIMESTAMP 0xFFFF0000 /* RX Packet Timestamp */ 104 - #define RX_PACKET_TIMESTAMP_SHIFT 16 105 - #define TRAFFIC_RESERVED 0x0000E000 /* Reserved */ 106 - #define TRAFFIC_RESERVED_SHIFT 13 107 - #define SV 0x00001000 /* sv */ 108 - #define SV_SHIFT 12 109 - #define RX_SEQUENCE_NUM 0x00000FFF /* RX Sequence Number */ 110 - #define RX_SEQUENCE_NUM_SHIFT 0 111 - 112 - __le32 tx_replay_cnt_low; /* TX Replay Counter Low */ 113 - 114 - __le16 tx_replay_cnt_high; /* TX Replay Counter High */ 115 - __le16 rx_replay_cnt_high; /* RX Replay Counter High */ 116 - 117 - __be32 rx_replay_cnt_low; /* RX Replay Counter Low */ 118 - } __attribute__((__packed__)); 119 - 120 - /* 121 - * Station Descriptors 122 - */ 123 - struct agnx_sta { 124 - __le32 tx_session_keys[4]; /* Transmit Session Key (0-3) */ 125 - __le32 rx_session_keys[4]; /* Receive Session Key (0-3) */ 126 - 127 - __le32 reg; 128 - #define ID_1 0xC0000000 /* id 1 */ 129 - #define ID_1_SHIFT 30 130 - #define ID_0 0x30000000 /* id 0 */ 131 - #define ID_0_SHIFT 28 132 - #define ENABLE_CONCATENATION 0x0FF00000 /* Enable concatenation */ 133 - #define ENABLE_CONCATENATION_SHIFT 20 134 - #define ENABLE_DECOMPRESSION 0x000FF000 /* Enable decompression */ 135 - #define ENABLE_DECOMPRESSION_SHIFT 12 136 - #define STA_RESERVED 0x00000C00 /* Reserved */ 137 - #define STA_RESERVED_SHIFT 10 138 - #define EAP 0x00000200 /* EAP */ 139 - #define EAP_SHIFT 9 140 - #define ED_NULL 0x00000100 /* ED NULL */ 141 - #define ED_NULL_SHIFT 8 142 - #define ENCRYPTION_POLICY 0x000000E0 /* Encryption Policy */ 143 - #define ENCRYPTION_POLICY_SHIFT 5 144 - #define DEFINED_KEY_ID 0x00000018 /* Defined Key ID */ 145 - #define DEFINED_KEY_ID_SHIFT 3 146 - #define FIXED_KEY 0x00000004 /* Fixed Key */ 147 - #define FIXED_KEY_SHIFT 2 148 - #define KEY_VALID 0x00000002 /* Key Valid */ 149 - #define KEY_VALID_SHIFT 1 150 - #define STATION_VALID 0x00000001 /* Station Valid */ 151 - #define STATION_VALID_SHIFT 0 152 - 153 - __le32 tx_aes_blks_unicast; /* TX AES Blks Unicast */ 154 - __le32 rx_aes_blks_unicast; /* RX AES Blks Unicast */ 155 - 156 - __le16 aes_format_err_unicast_cnt; /* AES Format Error Unicast Counts */ 157 - __le16 aes_replay_unicast; /* AES Replay Unicast */ 158 - 159 - __le16 aes_decrypt_err_unicast; /* AES Decrypt Error Unicast */ 160 - __le16 aes_decrypt_err_default; /* AES Decrypt Error default */ 161 - 162 - __le16 single_retry_packets; /* Single Retry Packets */ 163 - __le16 failed_tx_packets; /* Failed Tx Packets */ 164 - 165 - __le16 muti_retry_packets; /* Multiple Retry Packets */ 166 - __le16 ack_timeouts; /* ACK Timeouts */ 167 - 168 - __le16 frag_tx_cnt; /* Fragment TX Counts */ 169 - __le16 rts_brq_sent; /* RTS Brq Sent */ 170 - 171 - __le16 tx_packets; /* TX Packets */ 172 - __le16 cts_back_timeout; /* CTS Back Timeout */ 173 - 174 - __le32 phy_stats_high; /* PHY Stats High */ 175 - __le32 phy_stats_low; /* PHY Stats Low */ 176 - 177 - struct agnx_sta_traffic traffic[8]; /* Traffic Class Structure (8) */ 178 - 179 - __le16 traffic_class0_frag_success; /* Traffic Class 0 Fragment Success */ 180 - __le16 traffic_class1_frag_success; /* Traffic Class 1 Fragment Success */ 181 - __le16 traffic_class2_frag_success; /* Traffic Class 2 Fragment Success */ 182 - __le16 traffic_class3_frag_success; /* Traffic Class 3 Fragment Success */ 183 - __le16 traffic_class4_frag_success; /* Traffic Class 4 Fragment Success */ 184 - __le16 traffic_class5_frag_success; /* Traffic Class 5 Fragment Success */ 185 - __le16 traffic_class6_frag_success; /* Traffic Class 6 Fragment Success */ 186 - __le16 traffic_class7_frag_success; /* Traffic Class 7 Fragment Success */ 187 - 188 - __le16 num_frag_non_prime_rates; /* number of Fragments for non-prime rates */ 189 - __le16 ack_timeout_non_prime_rates; /* ACK Timeout for non-prime rates */ 190 - 191 - } __attribute__((__packed__)); 192 - 193 - 194 - struct agnx_beacon_hdr { 195 - struct agnx_sta_power power; /* Tx Station Power Template */ 196 - u8 phy_hdr[6]; /* PHY Hdr */ 197 - u8 frame_len_lo; /* Frame Length Lo */ 198 - u8 frame_len_hi; /* Frame Length Hi */ 199 - u8 mac_hdr[24]; /* MAC Header */ 200 - /* FIXME */ 201 - /* 802.11(abg) beacon */ 202 - } __attribute__((__packed__)); 203 - 204 - void hash_write(struct agnx_priv *priv, const u8 *mac_addr, u8 sta_id); 205 - void hash_dump(struct agnx_priv *priv, u8 sta_id); 206 - void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id); 207 - void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id); 208 - 209 - void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx); 210 - void set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, 211 - unsigned int sta_idx); 212 - void get_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq, 213 - unsigned int sta_idx, unsigned int wq_idx); 214 - void set_sta_tx_wq(struct agnx_priv *priv, struct agnx_sta_tx_wq *tx_wq, 215 - unsigned int sta_idx, unsigned int wq_idx); 216 - void get_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx); 217 - void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int sta_idx); 218 - 219 - void sta_power_init(struct agnx_priv *priv, unsigned int num); 220 - void sta_init(struct agnx_priv *priv, unsigned int num); 221 - 222 - #endif /* AGNX_STA_H_ */
-168
drivers/staging/agnx/table.c
··· 1 - #include <linux/pci.h> 2 - #include <linux/delay.h> 3 - #include "agnx.h" 4 - #include "debug.h" 5 - #include "phy.h" 6 - 7 - static const u32 8 - tx_fir_table[] = { 0x19, 0x5d, 0xce, 0x151, 0x1c3, 0x1ff, 0x1ea, 0x17c, 0xcf, 9 - 0x19, 0x38e, 0x350, 0x362, 0x3ad, 0x5, 0x44, 0x59, 0x49, 10 - 0x21, 0x3f7, 0x3e0, 0x3e3, 0x3f3, 0x0 }; 11 - 12 - void tx_fir_table_init(struct agnx_priv *priv) 13 - { 14 - void __iomem *ctl = priv->ctl; 15 - int i; 16 - 17 - for (i = 0; i < ARRAY_SIZE(tx_fir_table); i++) 18 - iowrite32(tx_fir_table[i], ctl + AGNX_FIR_BASE + i*4); 19 - } /* fir_table_setup */ 20 - 21 - 22 - static const u32 23 - gain_table[] = { 0x8, 0x8, 0xf, 0x13, 0x17, 0x1b, 0x1f, 0x23, 0x27, 0x2b, 24 - 0x2f, 0x33, 0x37, 0x3b, 0x3f, 0x43, 0x47, 0x4b, 0x4f, 25 - 0x53, 0x57, 0x5b, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 26 - 0x5f, 0x5f, 0x5f, 0x5f }; 27 - 28 - void gain_table_init(struct agnx_priv *priv) 29 - { 30 - void __iomem *ctl = priv->ctl; 31 - int i; 32 - 33 - for (i = 0; i < ARRAY_SIZE(gain_table); i++) { 34 - iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4); 35 - iowrite32(gain_table[i], ctl + AGNX_GAIN_TABLE + i*4 + 0x80); 36 - } 37 - } /* gain_table_init */ 38 - 39 - void monitor_gain_table_init(struct agnx_priv *priv) 40 - { 41 - void __iomem *ctl = priv->ctl; 42 - unsigned int i; 43 - 44 - for (i = 0; i < 0x44; i += 4) { 45 - iowrite32(0x61, ctl + AGNX_MONGCR_BASE + i); 46 - iowrite32(0x61, ctl + AGNX_MONGCR_BASE + 0x200 + i); 47 - } 48 - for (i = 0x44; i < 0x64; i += 4) { 49 - iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + i); 50 - iowrite32(0x6e, ctl + AGNX_MONGCR_BASE + 0x200 + i); 51 - } 52 - for (i = 0x64; i < 0x94; i += 4) { 53 - iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + i); 54 - iowrite32(0x7a, ctl + AGNX_MONGCR_BASE + 0x200 + i); 55 - } 56 - for (i = 0x94; i < 0xdc; i += 4) { 57 - iowrite32(0x87, ctl + AGNX_MONGCR_BASE + i); 58 - iowrite32(0x87, ctl + AGNX_MONGCR_BASE + 0x200 + i); 59 - } 60 - for (i = 0xdc; i < 0x148; i += 4) { 61 - iowrite32(0x95, ctl + AGNX_MONGCR_BASE + i); 62 - iowrite32(0x95, ctl + AGNX_MONGCR_BASE + 0x200 + i); 63 - } 64 - for (i = 0x148; i < 0x1e8; i += 4) { 65 - iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + i); 66 - iowrite32(0xa2, ctl + AGNX_MONGCR_BASE + 0x200 + i); 67 - } 68 - for (i = 0x1e8; i <= 0x1fc; i += 4) { 69 - iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + i); 70 - iowrite32(0xb0, ctl + AGNX_MONGCR_BASE + 0x200 + i); 71 - } 72 - } /* monitor_gain_table_init */ 73 - 74 - 75 - void routing_table_init(struct agnx_priv *priv) 76 - { 77 - void __iomem *ctl = priv->ctl; 78 - unsigned int type, subtype; 79 - u32 reg; 80 - 81 - disable_receiver(priv); 82 - 83 - for (type = 0; type < 0x3; type++) { 84 - for (subtype = 0; subtype < 0x10; subtype++) { 85 - /* 1. Set Routing table to R/W and to Return status on Read */ 86 - reg = (type << ROUTAB_TYPE_SHIFT) | 87 - (subtype << ROUTAB_SUBTYPE_SHIFT); 88 - reg |= (1 << ROUTAB_RW_SHIFT) | (1 << ROUTAB_STATUS_SHIFT); 89 - if (type == ROUTAB_TYPE_DATA) { 90 - /* NULL goes to RFP */ 91 - if (subtype == ROUTAB_SUBTYPE_NULL) 92 - /* reg |= ROUTAB_ROUTE_RFP; */ 93 - reg |= ROUTAB_ROUTE_CPU; 94 - /* QOS NULL goes to CPU */ 95 - else if (subtype == ROUTAB_SUBTYPE_QOSNULL) 96 - reg |= ROUTAB_ROUTE_CPU; 97 - /* All Data and QOS data subtypes go to Encryption */ 98 - else if ((subtype == ROUTAB_SUBTYPE_DATA) || 99 - (subtype == ROUTAB_SUBTYPE_DATAACK) || 100 - (subtype == ROUTAB_SUBTYPE_DATAPOLL) || 101 - (subtype == ROUTAB_SUBTYPE_DATAPOLLACK) || 102 - (subtype == ROUTAB_SUBTYPE_QOSDATA) || 103 - (subtype == ROUTAB_SUBTYPE_QOSDATAACK) || 104 - (subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) || 105 - (subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL)) 106 - reg |= ROUTAB_ROUTE_ENCRY; 107 - /* reg |= ROUTAB_ROUTE_CPU; */ 108 - /*Drop NULL and QOS NULL ack, poll and poll ack*/ 109 - else if ((subtype == ROUTAB_SUBTYPE_NULLACK) || 110 - (subtype == ROUTAB_SUBTYPE_QOSNULLACK) || 111 - (subtype == ROUTAB_SUBTYPE_NULLPOLL) || 112 - (subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) || 113 - (subtype == ROUTAB_SUBTYPE_NULLPOLLACK) || 114 - (subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK)) 115 - /* reg |= ROUTAB_ROUTE_DROP; */ 116 - reg |= ROUTAB_ROUTE_CPU; 117 - } else { 118 - reg |= (ROUTAB_ROUTE_CPU); 119 - } 120 - iowrite32(reg, ctl + AGNX_RXM_ROUTAB); 121 - /* Check to verify that the status bit cleared */ 122 - routing_table_delay(); 123 - } 124 - } 125 - enable_receiver(priv); 126 - } /* routing_table_init */ 127 - 128 - void tx_engine_lookup_tbl_init(struct agnx_priv *priv) 129 - { 130 - void __iomem *data = priv->data; 131 - unsigned int i; 132 - 133 - for (i = 0; i <= 28; i += 4) 134 - iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i); 135 - for (i = 32; i <= 120; i += 8) { 136 - iowrite32(0x1e58, data + AGNX_ENGINE_LOOKUP_TBL + i); 137 - iowrite32(0xb00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4); 138 - } 139 - 140 - for (i = 128; i <= 156; i += 4) 141 - iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i); 142 - for (i = 160; i <= 248; i += 8) { 143 - iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i); 144 - iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4); 145 - } 146 - 147 - for (i = 256; i <= 284; i += 4) 148 - iowrite32(0x980c, data + AGNX_ENGINE_LOOKUP_TBL + i); 149 - for (i = 288; i <= 376; i += 8) { 150 - iowrite32(0x1a58, data + AGNX_ENGINE_LOOKUP_TBL + i); 151 - iowrite32(0x1858, data + AGNX_ENGINE_LOOKUP_TBL + i + 4); 152 - } 153 - 154 - for (i = 512; i <= 540; i += 4) 155 - iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i); 156 - for (i = 544; i <= 632; i += 8) { 157 - iowrite32(0x2058, data + AGNX_ENGINE_LOOKUP_TBL + i); 158 - iowrite32(0xc00c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4); 159 - } 160 - 161 - for (i = 640; i <= 668; i += 4) 162 - iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i); 163 - for (i = 672; i <= 764; i += 8) { 164 - iowrite32(0x2258, data + AGNX_ENGINE_LOOKUP_TBL + i); 165 - iowrite32(0xc80c, data + AGNX_ENGINE_LOOKUP_TBL + i + 4); 166 - } 167 - } 168 -
-10
drivers/staging/agnx/table.h
··· 1 - #ifndef AGNX_TABLE_H_ 2 - #define AGNX_TABLE_H_ 3 - 4 - void tx_fir_table_init(struct agnx_priv *priv); 5 - void gain_table_init(struct agnx_priv *priv); 6 - void monitor_gain_table_init(struct agnx_priv *priv); 7 - void routing_table_init(struct agnx_priv *priv); 8 - void tx_engine_lookup_tbl_init(struct agnx_priv *priv); 9 - 10 - #endif /* AGNX_TABLE_H_ */
-836
drivers/staging/agnx/xmit.c
··· 1 - /** 2 - * Airgo MIMO wireless driver 3 - * 4 - * Copyright (c) 2007 Li YanBo <dreamfly281@gmail.com> 5 - 6 - * Thanks for Jeff Williams <angelbane@gmail.com> do reverse engineer 7 - * works and published the SPECS at http://airgo.wdwconsulting.net/mymoin 8 - 9 - * This program is free software; you can redistribute it and/or modify 10 - * it under the terms of the GNU General Public License version 2 as 11 - * published by the Free Software Foundation. 12 - */ 13 - 14 - #include <linux/pci.h> 15 - #include <linux/delay.h> 16 - #include "agnx.h" 17 - #include "debug.h" 18 - #include "phy.h" 19 - 20 - unsigned int rx_frame_cnt; 21 - /* unsigned int local_tx_sent_cnt = 0; */ 22 - 23 - static inline void disable_rx_engine(struct agnx_priv *priv) 24 - { 25 - void __iomem *ctl = priv->ctl; 26 - iowrite32(0x100, ctl + AGNX_CIR_RXCTL); 27 - /* Wait for RX Control to have the Disable Rx Interrupt (0x100) set */ 28 - ioread32(ctl + AGNX_CIR_RXCTL); 29 - } 30 - 31 - static inline void enable_rx_engine(struct agnx_priv *priv) 32 - { 33 - void __iomem *ctl = priv->ctl; 34 - iowrite32(0x80, ctl + AGNX_CIR_RXCTL); 35 - ioread32(ctl + AGNX_CIR_RXCTL); 36 - } 37 - 38 - inline void disable_rx_interrupt(struct agnx_priv *priv) 39 - { 40 - void __iomem *ctl = priv->ctl; 41 - u32 reg; 42 - 43 - disable_rx_engine(priv); 44 - reg = ioread32(ctl + AGNX_CIR_RXCFG); 45 - reg &= ~0x20; 46 - iowrite32(reg, ctl + AGNX_CIR_RXCFG); 47 - ioread32(ctl + AGNX_CIR_RXCFG); 48 - } 49 - 50 - inline void enable_rx_interrupt(struct agnx_priv *priv) 51 - { 52 - void __iomem *ctl = priv->ctl; 53 - u32 reg; 54 - 55 - reg = ioread32(ctl + AGNX_CIR_RXCFG); 56 - reg |= 0x20; 57 - iowrite32(reg, ctl + AGNX_CIR_RXCFG); 58 - ioread32(ctl + AGNX_CIR_RXCFG); 59 - enable_rx_engine(priv); 60 - } 61 - 62 - static inline void rx_desc_init(struct agnx_priv *priv, unsigned int idx) 63 - { 64 - struct agnx_desc *desc = priv->rx.desc + idx; 65 - struct agnx_info *info = priv->rx.info + idx; 66 - 67 - memset(info, 0, sizeof(*info)); 68 - 69 - info->dma_len = IEEE80211_MAX_RTS_THRESHOLD + sizeof(struct agnx_hdr); 70 - info->skb = dev_alloc_skb(info->dma_len); 71 - if (info->skb == NULL) 72 - agnx_bug("refill err"); 73 - 74 - info->mapping = pci_map_single(priv->pdev, skb_tail_pointer(info->skb), 75 - info->dma_len, PCI_DMA_FROMDEVICE); 76 - memset(desc, 0, sizeof(*desc)); 77 - desc->dma_addr = cpu_to_be32(info->mapping); 78 - /* Set the owner to the card */ 79 - desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER); 80 - } 81 - 82 - static inline void rx_desc_reinit(struct agnx_priv *priv, unsigned int idx) 83 - { 84 - struct agnx_info *info = priv->rx.info + idx; 85 - 86 - /* Cause ieee80211 will free the skb buffer, so we needn't to free it again?! */ 87 - pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE); 88 - rx_desc_init(priv, idx); 89 - } 90 - 91 - static inline void rx_desc_reusing(struct agnx_priv *priv, unsigned int idx) 92 - { 93 - struct agnx_desc *desc = priv->rx.desc + idx; 94 - struct agnx_info *info = priv->rx.info + idx; 95 - 96 - memset(desc, 0, sizeof(*desc)); 97 - desc->dma_addr = cpu_to_be32(info->mapping); 98 - /* Set the owner to the card */ 99 - desc->frag = cpu_to_be32(be32_to_cpu(desc->frag) | OWNER); 100 - } 101 - 102 - static void rx_desc_free(struct agnx_priv *priv, unsigned int idx) 103 - { 104 - struct agnx_desc *desc = priv->rx.desc + idx; 105 - struct agnx_info *info = priv->rx.info + idx; 106 - 107 - BUG_ON(!desc || !info); 108 - if (info->mapping) 109 - pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_FROMDEVICE); 110 - if (info->skb) 111 - dev_kfree_skb(info->skb); 112 - memset(info, 0, sizeof(*info)); 113 - memset(desc, 0, sizeof(*desc)); 114 - } 115 - 116 - static inline void __tx_desc_free(struct agnx_priv *priv, 117 - struct agnx_desc *desc, struct agnx_info *info) 118 - { 119 - BUG_ON(!desc || !info); 120 - /* TODO make sure mapping, skb and len are consistency */ 121 - if (info->mapping) 122 - pci_unmap_single(priv->pdev, info->mapping, 123 - info->dma_len, PCI_DMA_TODEVICE); 124 - if (info->type == PACKET) 125 - dev_kfree_skb(info->skb); 126 - 127 - memset(info, 0, sizeof(*info)); 128 - memset(desc, 0, sizeof(*desc)); 129 - } 130 - 131 - static void txm_desc_free(struct agnx_priv *priv, unsigned int idx) 132 - { 133 - struct agnx_desc *desc = priv->txm.desc + idx; 134 - struct agnx_info *info = priv->txm.info + idx; 135 - 136 - __tx_desc_free(priv, desc, info); 137 - } 138 - 139 - static void txd_desc_free(struct agnx_priv *priv, unsigned int idx) 140 - { 141 - struct agnx_desc *desc = priv->txd.desc + idx; 142 - struct agnx_info *info = priv->txd.info + idx; 143 - 144 - __tx_desc_free(priv, desc, info); 145 - } 146 - 147 - int fill_rings(struct agnx_priv *priv) 148 - { 149 - void __iomem *ctl = priv->ctl; 150 - unsigned int i; 151 - u32 reg; 152 - AGNX_TRACE; 153 - 154 - priv->txd.idx_sent = priv->txm.idx_sent = 0; 155 - priv->rx.idx = priv->txm.idx = priv->txd.idx = 0; 156 - 157 - for (i = 0; i < priv->rx.size; i++) 158 - rx_desc_init(priv, i); 159 - for (i = 0; i < priv->txm.size; i++) { 160 - memset(priv->txm.desc + i, 0, sizeof(struct agnx_desc)); 161 - memset(priv->txm.info + i, 0, sizeof(struct agnx_info)); 162 - } 163 - for (i = 0; i < priv->txd.size; i++) { 164 - memset(priv->txd.desc + i, 0, sizeof(struct agnx_desc)); 165 - memset(priv->txd.info + i, 0, sizeof(struct agnx_info)); 166 - } 167 - 168 - /* FIXME Set the card RX TXM and TXD address */ 169 - agnx_write32(ctl, AGNX_CIR_RXCMSTART, priv->rx.dma); 170 - agnx_write32(ctl, AGNX_CIR_RXCMEND, priv->txm.dma); 171 - 172 - agnx_write32(ctl, AGNX_CIR_TXMSTART, priv->txm.dma); 173 - agnx_write32(ctl, AGNX_CIR_TXMEND, priv->txd.dma); 174 - 175 - agnx_write32(ctl, AGNX_CIR_TXDSTART, priv->txd.dma); 176 - agnx_write32(ctl, AGNX_CIR_TXDEND, priv->txd.dma + 177 - sizeof(struct agnx_desc) * priv->txd.size); 178 - 179 - /* FIXME Relinquish control of rings to card */ 180 - reg = agnx_read32(ctl, AGNX_CIR_BLKCTL); 181 - reg &= ~0x800; 182 - agnx_write32(ctl, AGNX_CIR_BLKCTL, reg); 183 - return 0; 184 - } /* fill_rings */ 185 - 186 - void unfill_rings(struct agnx_priv *priv) 187 - { 188 - unsigned long flags; 189 - unsigned int i; 190 - AGNX_TRACE; 191 - 192 - spin_lock_irqsave(&priv->lock, flags); 193 - 194 - for (i = 0; i < priv->rx.size; i++) 195 - rx_desc_free(priv, i); 196 - for (i = 0; i < priv->txm.size; i++) 197 - txm_desc_free(priv, i); 198 - for (i = 0; i < priv->txd.size; i++) 199 - txd_desc_free(priv, i); 200 - 201 - spin_unlock_irqrestore(&priv->lock, flags); 202 - } 203 - 204 - /* Extract the bitrate out of a CCK PLCP header. 205 - copy from bcm43xx driver */ 206 - static inline u8 agnx_plcp_get_bitrate_cck(__be32 *phyhdr_11b) 207 - { 208 - /* FIXME */ 209 - switch (*(u8 *)phyhdr_11b) { 210 - case 0x0A: 211 - return 0; 212 - case 0x14: 213 - return 1; 214 - case 0x37: 215 - return 2; 216 - case 0x6E: 217 - return 3; 218 - } 219 - agnx_bug("Wrong plcp rate"); 220 - return 0; 221 - } 222 - 223 - /* FIXME */ 224 - static inline u8 agnx_plcp_get_bitrate_ofdm(__be32 *phyhdr_11g) 225 - { 226 - u8 rate = *(u8 *)phyhdr_11g & 0xF; 227 - 228 - printk(PFX "G mode rate is 0x%x\n", rate); 229 - return rate; 230 - } 231 - 232 - /* FIXME */ 233 - static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr, 234 - struct ieee80211_rx_status *stat) 235 - { 236 - void __iomem *ctl = priv->ctl; 237 - u8 *rssi; 238 - u32 noise; 239 - /* FIXME just for test */ 240 - int snr = 40; /* signal-to-noise ratio */ 241 - 242 - memset(stat, 0, sizeof(*stat)); 243 - /* RSSI */ 244 - rssi = (u8 *)&hdr->phy_stats_lo; 245 - /* stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */ 246 - /* Noise */ 247 - noise = ioread32(ctl + AGNX_GCR_NOISE0); 248 - noise += ioread32(ctl + AGNX_GCR_NOISE1); 249 - noise += ioread32(ctl + AGNX_GCR_NOISE2); 250 - stat->noise = noise / 3; 251 - /* Signal quality */ 252 - /* snr = stat->ssi - stat->noise; */ 253 - if (snr >= 0 && snr < 40) 254 - stat->signal = 5 * snr / 2; 255 - else if (snr >= 40) 256 - stat->signal = 100; 257 - else 258 - stat->signal = 0; 259 - 260 - 261 - if (hdr->_11b0 && !hdr->_11g0) { 262 - stat->rate_idx = agnx_plcp_get_bitrate_cck(&hdr->_11b0); 263 - } else if (!hdr->_11b0 && hdr->_11g0) { 264 - printk(PFX "RX: Found G mode packet\n"); 265 - stat->rate_idx = agnx_plcp_get_bitrate_ofdm(&hdr->_11g0); 266 - } else 267 - agnx_bug("Unknown packets type"); 268 - 269 - 270 - stat->band = IEEE80211_BAND_2GHZ; 271 - stat->freq = agnx_channels[priv->channel - 1].center_freq; 272 - /* stat->antenna = 3; 273 - stat->mactime = be32_to_cpu(hdr->time_stamp); 274 - stat->channel = priv->channel; */ 275 - } 276 - 277 - static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr, 278 - struct sk_buff *skb) 279 - { 280 - u16 fctl; 281 - unsigned int hdrlen; 282 - 283 - fctl = le16_to_cpu(ieeehdr->frame_control); 284 - hdrlen = ieee80211_hdrlen(fctl); 285 - /* FIXME */ 286 - if (hdrlen < (2+2+6)/*minimum hdr*/ || 287 - hdrlen > sizeof(struct ieee80211_mgmt)) { 288 - printk(KERN_ERR PFX "hdr len is %d\n", hdrlen); 289 - agnx_bug("Wrong ieee80211 hdr detected"); 290 - } 291 - skb_push(skb, hdrlen); 292 - memcpy(skb->data, ieeehdr, hdrlen); 293 - } /* combine_hdr_frag */ 294 - 295 - static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr, 296 - unsigned packet_len) 297 - { 298 - if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) { 299 - printk(PFX "RX: CRC check fail\n"); 300 - goto drop; 301 - } 302 - if (packet_len > 2048) { 303 - printk(PFX "RX: Too long packet detected\n"); 304 - goto drop; 305 - } 306 - 307 - /* FIXME Just usable for Promious Mode, for Manage mode exclude FCS */ 308 - /* if (packet_len - sizeof(*agnxhdr) < FCS_LEN) { */ 309 - /* printk(PFX "RX: Too short packet detected\n"); */ 310 - /* goto drop; */ 311 - /* } */ 312 - return 0; 313 - drop: 314 - priv->stats.dot11FCSErrorCount++; 315 - return -1; 316 - } 317 - 318 - void handle_rx_irq(struct agnx_priv *priv) 319 - { 320 - struct ieee80211_rx_status status; 321 - unsigned int len; 322 - /* AGNX_TRACE; */ 323 - 324 - do { 325 - struct agnx_desc *desc; 326 - u32 frag; 327 - struct agnx_info *info; 328 - struct agnx_hdr *hdr; 329 - struct sk_buff *skb; 330 - unsigned int i = priv->rx.idx % priv->rx.size; 331 - 332 - desc = priv->rx.desc + i; 333 - frag = be32_to_cpu(desc->frag); 334 - if (frag & OWNER) 335 - break; 336 - 337 - info = priv->rx.info + i; 338 - skb = info->skb; 339 - hdr = (struct agnx_hdr *)(skb->data); 340 - 341 - len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT; 342 - if (agnx_packet_check(priv, hdr, len) == -1) { 343 - rx_desc_reusing(priv, i); 344 - continue; 345 - } 346 - skb_put(skb, len); 347 - 348 - do { 349 - u16 fctl; 350 - fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control); 351 - if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */ 352 - dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX"); 353 - } while (0); 354 - 355 - if (hdr->_11b0 && !hdr->_11g0) { 356 - /* int j; 357 - u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) 358 - ->frame_control); 359 - if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { 360 - agnx_print_rx_hdr(hdr); 361 - agnx_print_sta(priv, BSSID_STAID); 362 - for (j = 0; j < 8; j++) 363 - agnx_print_sta_tx_wq(priv, BSSID_STAID, j); 364 - } */ 365 - 366 - get_rx_stats(priv, hdr, &status); 367 - skb_pull(skb, sizeof(*hdr)); 368 - combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb); 369 - } else if (!hdr->_11b0 && hdr->_11g0) { 370 - /* int j; */ 371 - agnx_print_rx_hdr(hdr); 372 - agnx_print_sta(priv, BSSID_STAID); 373 - /* for (j = 0; j < 8; j++) */ 374 - agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); 375 - 376 - print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE, 377 - skb->data, skb->len + 8); 378 - 379 - /* if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */ 380 - get_rx_stats(priv, hdr, &status); 381 - skb_pull(skb, sizeof(*hdr)); 382 - combine_hdr_frag((struct ieee80211_hdr *) 383 - ((void *)&hdr->mac_hdr), skb); 384 - /* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */ 385 - } else 386 - agnx_bug("Unknown packets type"); 387 - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); 388 - ieee80211_rx_irqsafe(priv->hw, skb); 389 - rx_desc_reinit(priv, i); 390 - 391 - } while (priv->rx.idx++); 392 - } /* handle_rx_irq */ 393 - 394 - static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring) 395 - { 396 - struct agnx_desc *desc; 397 - struct agnx_info *info; 398 - unsigned int idx; 399 - 400 - for (idx = ring->idx_sent; idx < ring->idx; idx++) { 401 - unsigned int i = idx % ring->size; 402 - u32 frag; 403 - 404 - desc = ring->desc + i; 405 - info = ring->info + i; 406 - 407 - frag = be32_to_cpu(desc->frag); 408 - if (frag & OWNER) { 409 - if (info->type == HEADER) 410 - break; 411 - else 412 - agnx_bug("TX error"); 413 - } 414 - 415 - pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE); 416 - 417 - do { 418 - /* int j; */ 419 - size_t len; 420 - len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len; 421 - /* if (len == 614) { */ 422 - /* agnx_print_desc(desc); */ 423 - if (info->type == PACKET) { 424 - /* agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */ 425 - /* agnx_print_sta_power(priv, LOCAL_STAID); */ 426 - /* agnx_print_sta(priv, LOCAL_STAID); */ 427 - /* for (j = 0; j < 8; j++) */ 428 - /* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */ 429 - /* agnx_print_sta_power(priv, BSSID_STAID); */ 430 - /* agnx_print_sta(priv, BSSID_STAID); */ 431 - /* for (j = 0; j < 8; j++) */ 432 - /* agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */ 433 - } 434 - /* } */ 435 - } while (0); 436 - 437 - if (info->type == PACKET) { 438 - /* dump_txm_registers(priv); 439 - dump_rxm_registers(priv); 440 - dump_bm_registers(priv); 441 - dump_cir_registers(priv); */ 442 - } 443 - 444 - if (info->type == PACKET) { 445 - /* struct ieee80211_hdr *hdr; */ 446 - struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb); 447 - 448 - skb_pull(info->skb, sizeof(struct agnx_hdr)); 449 - memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len); 450 - 451 - /* dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */ 452 - /* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */ 453 - /* info->skb->data, info->skb->len); */ 454 - 455 - if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) 456 - txi->flags |= IEEE80211_TX_STAT_ACK; 457 - 458 - ieee80211_tx_status_irqsafe(priv->hw, info->skb); 459 - 460 - 461 - /* info->tx_status.queue_number = (ring->size - i) / 2; */ 462 - /* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */ 463 - /* } else */ 464 - /* dev_kfree_skb_irq(info->skb); */ 465 - } 466 - memset(desc, 0, sizeof(*desc)); 467 - memset(info, 0, sizeof(*info)); 468 - } 469 - 470 - ring->idx_sent = idx; 471 - /* TODO fill the priv->low_level_stats */ 472 - 473 - /* ieee80211_wake_queue(priv->hw, 0); */ 474 - } 475 - 476 - void handle_txm_irq(struct agnx_priv *priv) 477 - { 478 - handle_tx_irq(priv, &priv->txm); 479 - } 480 - 481 - void handle_txd_irq(struct agnx_priv *priv) 482 - { 483 - handle_tx_irq(priv, &priv->txd); 484 - } 485 - 486 - void handle_other_irq(struct agnx_priv *priv) 487 - { 488 - /* void __iomem *ctl = priv->ctl; */ 489 - u32 status = priv->irq_status; 490 - void __iomem *ctl = priv->ctl; 491 - u32 reg; 492 - 493 - if (status & IRQ_TX_BEACON) { 494 - iowrite32(IRQ_TX_BEACON, ctl + AGNX_INT_STAT); 495 - printk(PFX "IRQ: TX Beacon control is 0X%.8X\n", ioread32(ctl + AGNX_TXM_BEACON_CTL)); 496 - printk(PFX "IRQ: TX Beacon rx frame num: %d\n", rx_frame_cnt); 497 - } 498 - if (status & IRQ_TX_RETRY) { 499 - reg = ioread32(ctl + AGNX_TXM_RETRYSTAID); 500 - printk(PFX "IRQ: TX Retry, RETRY STA ID is %x\n", reg); 501 - } 502 - if (status & IRQ_TX_ACTIVITY) 503 - printk(PFX "IRQ: TX Activity\n"); 504 - if (status & IRQ_RX_ACTIVITY) 505 - printk(PFX "IRQ: RX Activity\n"); 506 - if (status & IRQ_RX_X) 507 - printk(PFX "IRQ: RX X\n"); 508 - if (status & IRQ_RX_Y) { 509 - reg = ioread32(ctl + AGNX_INT_MASK); 510 - reg &= ~IRQ_RX_Y; 511 - iowrite32(reg, ctl + AGNX_INT_MASK); 512 - iowrite32(IRQ_RX_Y, ctl + AGNX_INT_STAT); 513 - printk(PFX "IRQ: RX Y\n"); 514 - } 515 - if (status & IRQ_RX_HASHHIT) { 516 - reg = ioread32(ctl + AGNX_INT_MASK); 517 - reg &= ~IRQ_RX_HASHHIT; 518 - iowrite32(reg, ctl + AGNX_INT_MASK); 519 - iowrite32(IRQ_RX_HASHHIT, ctl + AGNX_INT_STAT); 520 - printk(PFX "IRQ: RX Hash Hit\n"); 521 - 522 - } 523 - if (status & IRQ_RX_FRAME) { 524 - reg = ioread32(ctl + AGNX_INT_MASK); 525 - reg &= ~IRQ_RX_FRAME; 526 - iowrite32(reg, ctl + AGNX_INT_MASK); 527 - iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT); 528 - printk(PFX "IRQ: RX Frame\n"); 529 - rx_frame_cnt++; 530 - } 531 - if (status & IRQ_ERR_INT) { 532 - iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT); 533 - /* agnx_hw_reset(priv); */ 534 - printk(PFX "IRQ: Error Interrupt\n"); 535 - } 536 - if (status & IRQ_TX_QUE_FULL) 537 - printk(PFX "IRQ: TX Workqueue Full\n"); 538 - if (status & IRQ_BANDMAN_ERR) 539 - printk(PFX "IRQ: Bandwidth Management Error\n"); 540 - if (status & IRQ_TX_DISABLE) 541 - printk(PFX "IRQ: TX Disable\n"); 542 - if (status & IRQ_RX_IVASESKEY) 543 - printk(PFX "IRQ: RX Invalid Session Key\n"); 544 - if (status & IRQ_REP_THHIT) 545 - printk(PFX "IRQ: Replay Threshold Hit\n"); 546 - if (status & IRQ_TIMER1) 547 - printk(PFX "IRQ: Timer1\n"); 548 - if (status & IRQ_TIMER_CNT) 549 - printk(PFX "IRQ: Timer Count\n"); 550 - if (status & IRQ_PHY_FASTINT) 551 - printk(PFX "IRQ: Phy Fast Interrupt\n"); 552 - if (status & IRQ_PHY_SLOWINT) 553 - printk(PFX "IRQ: Phy Slow Interrupt\n"); 554 - if (status & IRQ_OTHER) 555 - printk(PFX "IRQ: 0x80000000\n"); 556 - } /* handle_other_irq */ 557 - 558 - 559 - static inline void route_flag_set(struct agnx_hdr *txhdr) 560 - { 561 - /* u32 reg = 0; */ 562 - 563 - /* FIXME */ 564 - /* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */ 565 - /* txhdr->reg5 = cpu_to_be32(reg); */ 566 - txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18); 567 - /* txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */ 568 - /* txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */ 569 - } 570 - 571 - /* Return 0 if no match */ 572 - static inline unsigned int get_power_level(unsigned int rate, unsigned int antennas_num) 573 - { 574 - unsigned int power_level; 575 - 576 - switch (rate) { 577 - case 10: 578 - case 20: 579 - case 55: 580 - case 60: 581 - case 90: 582 - case 120: 583 - power_level = 22; 584 - break; 585 - 586 - case 180: 587 - power_level = 19; 588 - break; 589 - 590 - case 240: 591 - power_level = 18; 592 - break; 593 - 594 - case 360: 595 - power_level = 16; 596 - break; 597 - 598 - case 480: 599 - power_level = 15; 600 - break; 601 - 602 - case 540: 603 - power_level = 14; 604 - break; 605 - default: 606 - agnx_bug("Error rate setting\n"); 607 - } 608 - 609 - if (power_level && (antennas_num == 2)) 610 - power_level -= 3; 611 - 612 - return power_level; 613 - } 614 - 615 - static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_info) 616 - { 617 - struct agnx_hdr *txhdr = (struct agnx_hdr *)tx_info->skb->data; 618 - size_t len; 619 - u16 fc = le16_to_cpu(*(__le16 *)&tx_info->hdr); 620 - u32 reg; 621 - 622 - memset(txhdr, 0, sizeof(*txhdr)); 623 - 624 - /* reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */ 625 - reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID); 626 - reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0); 627 - txhdr->reg4 = cpu_to_be32(reg); 628 - 629 - /* Set the Hardware Sequence Number to 1? */ 630 - reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0); 631 - /* reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */ 632 - reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len); 633 - txhdr->reg1 = cpu_to_be32(reg); 634 - /* Set the agnx_hdr's MAC header */ 635 - memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len); 636 - 637 - reg = agnx_set_bits(ACK, ACK_SHIFT, 1); 638 - /* reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */ 639 - reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0); 640 - /* reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */ 641 - reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0); 642 - reg |= agnx_set_bits(TM, TM_SHIFT, 0); 643 - txhdr->reg0 = cpu_to_be32(reg); 644 - 645 - /* Set the long and short retry limits */ 646 - txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count; 647 - txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count; 648 - 649 - /* FIXME */ 650 - len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN; 651 - if (fc & IEEE80211_FCTL_PROTECTED) 652 - len += 8; 653 - len = 2398; 654 - reg = agnx_set_bits(FRAG_SIZE, FRAG_SIZE_SHIFT, len); 655 - len = tx_info->skb->len - sizeof(*txhdr); 656 - reg |= agnx_set_bits(PAYLOAD_LEN, PAYLOAD_LEN_SHIFT, len); 657 - txhdr->reg3 = cpu_to_be32(reg); 658 - 659 - route_flag_set(txhdr); 660 - } /* fill_hdr */ 661 - 662 - static void txm_power_set(struct agnx_priv *priv, 663 - struct ieee80211_tx_info *txi) 664 - { 665 - struct agnx_sta_power power; 666 - u32 reg; 667 - 668 - /* FIXME */ 669 - if (txi->control.rates[0].idx < 0) { 670 - /* For B mode Short Preamble */ 671 - reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT); 672 - /* control->tx_rate = -control->tx_rate; */ 673 - } else 674 - reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G); 675 - /* reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */ 676 - reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB); 677 - reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB); 678 - /* reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */ 679 - reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20); 680 - /* if rate < 11M set it to 0 */ 681 - reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1); 682 - /* reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */ 683 - /* reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */ 684 - 685 - power.reg = reg; 686 - /* power.reg = cpu_to_le32(reg); */ 687 - 688 - /* set_sta_power(priv, &power, LOCAL_STAID); */ 689 - set_sta_power(priv, &power, BSSID_STAID); 690 - } 691 - 692 - static inline int tx_packet_check(struct sk_buff *skb) 693 - { 694 - unsigned int ieee_len = ieee80211_get_hdrlen_from_skb(skb); 695 - if (skb->len > 2048) { 696 - printk(KERN_ERR PFX "length is %d\n", skb->len); 697 - agnx_bug("Too long TX skb"); 698 - return -1; 699 - } 700 - /* FIXME */ 701 - if (skb->len == ieee_len) { 702 - printk(PFX "A strange TX packet\n"); 703 - return -1; 704 - /* tx_faile_irqsafe(); */ 705 - } 706 - return 0; 707 - } 708 - 709 - static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb, 710 - struct agnx_ring *ring) 711 - { 712 - struct agnx_desc *hdr_desc, *frag_desc; 713 - struct agnx_info *hdr_info, *frag_info; 714 - struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); 715 - unsigned long flags; 716 - unsigned int i; 717 - 718 - spin_lock_irqsave(&priv->lock, flags); 719 - 720 - /* The RX interrupt need be Disable until this TX packet 721 - is handled in the next tx interrupt */ 722 - disable_rx_interrupt(priv); 723 - 724 - i = ring->idx; 725 - ring->idx += 2; 726 - /* if (priv->txm_idx - priv->txm_idx_sent == AGNX_TXM_RING_SIZE - 2) */ 727 - /* ieee80211_stop_queue(priv->hw, 0); */ 728 - 729 - /* Set agnx header's info and desc */ 730 - i %= ring->size; 731 - hdr_desc = ring->desc + i; 732 - hdr_info = ring->info + i; 733 - hdr_info->hdr_len = ieee80211_get_hdrlen_from_skb(skb); 734 - memcpy(&hdr_info->hdr, skb->data, hdr_info->hdr_len); 735 - 736 - /* Add the agnx header to the front of the SKB */ 737 - skb_push(skb, sizeof(struct agnx_hdr) - hdr_info->hdr_len); 738 - 739 - hdr_info->txi = txi; 740 - hdr_info->dma_len = sizeof(struct agnx_hdr); 741 - hdr_info->skb = skb; 742 - hdr_info->type = HEADER; 743 - fill_agnx_hdr(priv, hdr_info); 744 - hdr_info->mapping = pci_map_single(priv->pdev, skb->data, 745 - hdr_info->dma_len, PCI_DMA_TODEVICE); 746 - do { 747 - u32 frag = 0; 748 - frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 1); 749 - frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 0); 750 - frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len); 751 - frag |= agnx_set_bits(FIRST_FRAG_LEN, FIRST_FRAG_LEN_SHIFT, 1); 752 - frag |= agnx_set_bits(OWNER, OWNER_SHIFT, 1); 753 - hdr_desc->frag = cpu_to_be32(frag); 754 - } while (0); 755 - hdr_desc->dma_addr = cpu_to_be32(hdr_info->mapping); 756 - 757 - 758 - /* Set Frag's info and desc */ 759 - i = (i + 1) % ring->size; 760 - frag_desc = ring->desc + i; 761 - frag_info = ring->info + i; 762 - memcpy(frag_info, hdr_info, sizeof(struct agnx_info)); 763 - frag_info->type = PACKET; 764 - frag_info->dma_len = skb->len - hdr_info->dma_len; 765 - frag_info->mapping = pci_map_single(priv->pdev, skb->data + hdr_info->dma_len, 766 - frag_info->dma_len, PCI_DMA_TODEVICE); 767 - do { 768 - u32 frag = 0; 769 - frag |= agnx_set_bits(FIRST_FRAG, FIRST_FRAG_SHIFT, 0); 770 - frag |= agnx_set_bits(LAST_FRAG, LAST_FRAG_SHIFT, 1); 771 - frag |= agnx_set_bits(PACKET_LEN, PACKET_LEN_SHIFT, skb->len); 772 - frag |= agnx_set_bits(SUB_FRAG_LEN, SUB_FRAG_LEN_SHIFT, frag_info->dma_len); 773 - frag_desc->frag = cpu_to_be32(frag); 774 - } while (0); 775 - frag_desc->dma_addr = cpu_to_be32(frag_info->mapping); 776 - 777 - txm_power_set(priv, txi); 778 - 779 - /* do { */ 780 - /* int j; */ 781 - /* size_t len; */ 782 - /* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */ 783 - /* if (len == 614) { */ 784 - /* agnx_print_desc(hdr_desc); */ 785 - /* agnx_print_desc(frag_desc); */ 786 - /* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */ 787 - /* agnx_print_sta_power(priv, LOCAL_STAID); */ 788 - /* agnx_print_sta(priv, LOCAL_STAID); */ 789 - /* for (j = 0; j < 8; j++) */ 790 - /* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */ 791 - /* agnx_print_sta_power(priv, BSSID_STAID); */ 792 - /* agnx_print_sta(priv, BSSID_STAID); */ 793 - /* for (j = 0; j < 8; j++) */ 794 - /* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */ 795 - /* } */ 796 - /* } while (0); */ 797 - 798 - spin_unlock_irqrestore(&priv->lock, flags); 799 - 800 - /* FIXME ugly code */ 801 - /* Trigger TXM */ 802 - do { 803 - u32 reg; 804 - reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL)); 805 - reg |= 0x8; 806 - iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL); 807 - } while (0); 808 - 809 - /* Trigger TXD */ 810 - do { 811 - u32 reg; 812 - reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL)); 813 - reg |= 0x8; 814 - iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL); 815 - } while (0); 816 - 817 - return 0; 818 - } 819 - 820 - int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb) 821 - { 822 - u16 fctl; 823 - 824 - if (tx_packet_check(skb)) 825 - return 0; 826 - 827 - /* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */ 828 - /* skb->data, skb->len); */ 829 - 830 - fctl = le16_to_cpu(*((__le16 *)skb->data)); 831 - 832 - if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) 833 - return __agnx_tx(priv, skb, &priv->txd); 834 - else 835 - return __agnx_tx(priv, skb, &priv->txm); 836 - }
-250
drivers/staging/agnx/xmit.h
··· 1 - #ifndef AGNX_XMIT_H_ 2 - #define AGNX_XMIT_H_ 3 - 4 - #include <net/mac80211.h> 5 - 6 - struct agnx_priv; 7 - 8 - static inline u32 agnx_set_bits(u32 mask, u8 shift, u32 value) 9 - { 10 - return (value << shift) & mask; 11 - } 12 - 13 - static inline u32 agnx_get_bits(u32 mask, u8 shift, u32 value) 14 - { 15 - return (value & mask) >> shift; 16 - } 17 - 18 - 19 - struct agnx_rx { 20 - __be16 rx_packet_duration; /* RX Packet Duration */ 21 - __be16 replay_cnt; /* Replay Count */ 22 - } __attribute__((__packed__)); 23 - 24 - 25 - struct agnx_tx { 26 - u8 long_retry_limit; /* Long Retry Limit */ 27 - u8 short_retry_limit; /* Short Retry Limit */ 28 - u8 long_retry_cnt; /* Long Retry Count */ 29 - u8 short_retry_cnt; /* Short Retry Count */ 30 - } __attribute__((__packed__)); 31 - 32 - 33 - /* Copy from bcm43xx */ 34 - #define P4D_BYT3S(magic, nr_bytes) u8 __p4dding##magic[nr_bytes] 35 - #define P4D_BYTES(line, nr_bytes) P4D_BYT3S(line, nr_bytes) 36 - #define PAD_BYTES(nr_bytes) P4D_BYTES(__LINE__, nr_bytes) 37 - 38 - #define P4D_BIT3S(magic, nr_bits) __be32 __padding##magic:nr_bits 39 - #define P4D_BITS(line, nr_bits) P4D_BIT3S(line, nr_bits) 40 - #define PAD_BITS(nr_bits) P4D_BITS(__LINE__, nr_bits) 41 - 42 - 43 - struct agnx_hdr { 44 - __be32 reg0; 45 - #define RTS 0x80000000 /* RTS */ 46 - #define RTS_SHIFT 31 47 - #define MULTICAST 0x40000000 /* multicast */ 48 - #define MULTICAST_SHIFT 30 49 - #define ACK 0x30000000 /* ACK */ 50 - #define ACK_SHIFT 28 51 - #define TM 0x08000000 /* TM */ 52 - #define TM_SHIFT 27 53 - #define RELAY 0x04000000 /* Relay */ 54 - #define RELAY_SHIFT 26 55 - /* PAD_BITS(4); */ 56 - #define REVISED_FCS 0x00380000 /* revised FCS */ 57 - #define REVISED_FCS_SHIFT 19 58 - #define NEXT_BUFFER_ADDR 0x0007FFFF /* Next Buffer Address */ 59 - #define NEXT_BUFFER_ADDR_SHIFT 0 60 - 61 - __be32 reg1; 62 - #define MAC_HDR_LEN 0xFC000000 /* MAC Header Length */ 63 - #define MAC_HDR_LEN_SHIFT 26 64 - #define DURATION_OVERIDE 0x02000000 /* Duration Override */ 65 - #define DURATION_OVERIDE_SHIFT 25 66 - #define PHY_HDR_OVERIDE 0x01000000 /* PHY Header Override */ 67 - #define PHY_HDR_OVERIDE_SHIFT 24 68 - #define CRC_FAIL 0x00800000 /* CRC fail */ 69 - #define CRC_FAIL_SHIFT 23 70 - /* PAD_BITS(1); */ 71 - #define SEQUENCE_NUMBER 0x00200000 /* Sequence Number */ 72 - #define SEQUENCE_NUMBER_SHIFT 21 73 - /* PAD_BITS(2); */ 74 - #define BUFF_HEAD_ADDR 0x0007FFFF /* Buffer Head Address */ 75 - #define BUFF_HEAD_ADDR_SHIFT 0 76 - 77 - __be32 reg2; 78 - #define PDU_COUNT 0xFC000000 /* PDU Count */ 79 - #define PDU_COUNT_SHIFT 26 80 - /* PAD_BITS(3); */ 81 - #define WEP_KEY 0x00600000 /* WEP Key # */ 82 - #define WEP_KEY_SHIFT 21 83 - #define USES_WEP_KEY 0x00100000 /* Uses WEP Key */ 84 - #define USES_WEP_KEY_SHIFT 20 85 - #define KEEP_ALIVE 0x00080000 /* Keep alive */ 86 - #define KEEP_ALIVE_SHIFT 19 87 - #define BUFF_TAIL_ADDR 0x0007FFFF /* Buffer Tail Address */ 88 - #define BUFF_TAIL_ADDR_SHIFT 0 89 - 90 - __be32 reg3; 91 - #define CTS_11G 0x80000000 /* CTS in 11g */ 92 - #define CTS_11G_SHIFT 31 93 - #define RTS_11G 0x40000000 /* RTS in 11g */ 94 - #define RTS_11G_SHIFT 30 95 - /* PAD_BITS(2); */ 96 - #define FRAG_SIZE 0x0FFF0000 /* fragment size */ 97 - #define FRAG_SIZE_SHIFT 16 98 - #define PAYLOAD_LEN 0x0000FFF0 /* payload length */ 99 - #define PAYLOAD_LEN_SHIFT 4 100 - #define FRAG_NUM 0x0000000F /* number of frags */ 101 - #define FRAG_NUM_SHIFT 0 102 - 103 - __be32 reg4; 104 - /* PAD_BITS(4); */ 105 - #define RELAY_STAID 0x0FFF0000 /* relayStald */ 106 - #define RELAY_STAID_SHIFT 16 107 - #define STATION_ID 0x0000FFF0 /* Station ID */ 108 - #define STATION_ID_SHIFT 4 109 - #define WORKQUEUE_ID 0x0000000F /* Workqueue ID */ 110 - #define WORKQUEUE_ID_SHIFT 0 111 - 112 - /* FIXME this register maybe is LE? */ 113 - __be32 reg5; 114 - /* PAD_BITS(4); */ 115 - #define ROUTE_HOST 0x0F000000 116 - #define ROUTE_HOST_SHIFT 24 117 - #define ROUTE_CARD_CPU 0x00F00000 118 - #define ROUTE_CARD_CPU_SHIFT 20 119 - #define ROUTE_ENCRYPTION 0x000F0000 120 - #define ROUTE_ENCRYPTION_SHIFT 16 121 - #define ROUTE_TX 0x0000F000 122 - #define ROUTE_TX_SHIFT 12 123 - #define ROUTE_RX1 0x00000F00 124 - #define ROUTE_RX1_SHIFT 8 125 - #define ROUTE_RX2 0x000000F0 126 - #define ROUTE_RX2_SHIFT 4 127 - #define ROUTE_COMPRESSION 0x0000000F 128 - #define ROUTE_COMPRESSION_SHIFT 0 129 - 130 - __be32 _11g0; /* 11g */ 131 - __be32 _11g1; /* 11g */ 132 - __be32 _11b0; /* 11b */ 133 - __be32 _11b1; /* 11b */ 134 - u8 mac_hdr[32]; /* MAC header */ 135 - 136 - __be16 rts_duration; /* RTS duration */ 137 - __be16 last_duration; /* Last duration */ 138 - __be16 sec_last_duration; /* Second to Last duration */ 139 - __be16 other_duration; /* Other duration */ 140 - __be16 tx_last_duration; /* TX Last duration */ 141 - __be16 tx_other_duration; /* TX Other Duration */ 142 - __be16 last_11g_len; /* Length of last 11g */ 143 - __be16 other_11g_len; /* Lenght of other 11g */ 144 - 145 - __be16 last_11b_len; /* Length of last 11b */ 146 - __be16 other_11b_len; /* Lenght of other 11b */ 147 - 148 - 149 - __be16 reg6; 150 - #define MBF 0xF000 /* mbf */ 151 - #define MBF_SHIFT 12 152 - #define RSVD4 0x0FFF /* rsvd4 */ 153 - #define RSVD4_SHIFT 0 154 - 155 - __be16 rx_frag_stat; /* RX fragmentation status */ 156 - 157 - __be32 time_stamp; /* TimeStamp */ 158 - __be32 phy_stats_hi; /* PHY stats hi */ 159 - __be32 phy_stats_lo; /* PHY stats lo */ 160 - __be32 mic_key0; /* MIC key 0 */ 161 - __be32 mic_key1; /* MIC key 1 */ 162 - 163 - union { /* RX/TX Union */ 164 - struct agnx_rx rx; 165 - struct agnx_tx tx; 166 - }; 167 - 168 - u8 rx_channel; /* Recieve Channel */ 169 - PAD_BYTES(3); 170 - 171 - u8 reserved[4]; 172 - } __attribute__((__packed__)); 173 - 174 - 175 - struct agnx_desc { 176 - #define PACKET_LEN 0xFFF00000 177 - #define PACKET_LEN_SHIFT 20 178 - /* ------------------------------------------------ */ 179 - #define FIRST_PACKET_MASK 0x00080000 180 - #define FIRST_PACKET_MASK_SHIFT 19 181 - #define FIRST_RESERV2 0x00040000 182 - #define FIRST_RESERV2_SHIFT 18 183 - #define FIRST_TKIP_ERROR 0x00020000 184 - #define FIRST_TKIP_ERROR_SHIFT 17 185 - #define FIRST_TKIP_PACKET 0x00010000 186 - #define FIRST_TKIP_PACKET_SHIFT 16 187 - #define FIRST_RESERV1 0x0000F000 188 - #define FIRST_RESERV1_SHIFT 12 189 - #define FIRST_FRAG_LEN 0x00000FF8 190 - #define FIRST_FRAG_LEN_SHIFT 3 191 - /* ------------------------------------------------ */ 192 - #define SUB_RESERV2 0x000c0000 193 - #define SUB_RESERV2_SHIFT 18 194 - #define SUB_TKIP_ERROR 0x00020000 195 - #define SUB_TKIP_ERROR_SHIFT 17 196 - #define SUB_TKIP_PACKET 0x00010000 197 - #define SUB_TKIP_PACKET_SHIFT 16 198 - #define SUB_RESERV1 0x00008000 199 - #define SUB_RESERV1_SHIFT 15 200 - #define SUB_FRAG_LEN 0x00007FF8 201 - #define SUB_FRAG_LEN_SHIFT 3 202 - /* ------------------------------------------------ */ 203 - #define FIRST_FRAG 0x00000004 204 - #define FIRST_FRAG_SHIFT 2 205 - #define LAST_FRAG 0x00000002 206 - #define LAST_FRAG_SHIFT 1 207 - #define OWNER 0x00000001 208 - #define OWNER_SHIFT 0 209 - __be32 frag; 210 - __be32 dma_addr; 211 - } __attribute__((__packed__)); 212 - 213 - enum {HEADER, PACKET}; 214 - 215 - struct agnx_info { 216 - struct sk_buff *skb; 217 - dma_addr_t mapping; 218 - u32 dma_len; /* dma buffer len */ 219 - /* Below fields only usful for tx */ 220 - u32 hdr_len; /* ieee80211 header length */ 221 - unsigned int type; 222 - struct ieee80211_tx_info *txi; 223 - struct ieee80211_hdr hdr; 224 - }; 225 - 226 - 227 - struct agnx_ring { 228 - struct agnx_desc *desc; 229 - dma_addr_t dma; 230 - struct agnx_info *info; 231 - /* Will lead to overflow when sent packet number enough? */ 232 - unsigned int idx; 233 - unsigned int idx_sent; /* only usful for txd and txm */ 234 - unsigned int size; 235 - }; 236 - 237 - #define AGNX_RX_RING_SIZE 128 238 - #define AGNX_TXD_RING_SIZE 256 239 - #define AGNX_TXM_RING_SIZE 128 240 - 241 - void disable_rx_interrupt(struct agnx_priv *priv); 242 - void enable_rx_interrupt(struct agnx_priv *priv); 243 - int fill_rings(struct agnx_priv *priv); 244 - void unfill_rings(struct agnx_priv *priv); 245 - void handle_rx_irq(struct agnx_priv *priv); 246 - void handle_txd_irq(struct agnx_priv *priv); 247 - void handle_txm_irq(struct agnx_priv *priv); 248 - void handle_other_irq(struct agnx_priv *priv); 249 - int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb); 250 - #endif /* AGNX_XMIT_H_ */
+1 -1
drivers/staging/comedi/Kconfig
··· 1 1 config COMEDI 2 2 tristate "Data acquisition support (comedi)" 3 3 default N 4 - depends on m 4 + depends on m && (PCI || PCMCIA || PCCARD || USB) 5 5 ---help--- 6 6 Enable support a wide range of data acquisition devices 7 7 for Linux.
+1 -1
drivers/staging/comedi/comedi_fops.c
··· 2337 2337 } 2338 2338 2339 2339 DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", 2340 - dev->minor, s - dev->subdevices, async->prealloc_bufsz); 2340 + dev->minor, (int)(s - dev->subdevices), async->prealloc_bufsz); 2341 2341 return 0; 2342 2342 } 2343 2343
+1 -1
drivers/staging/comedi/drivers/cb_das16_cs.c
··· 744 744 745 745 /* Initialize the pcmcia_device structure */ 746 746 /* Interrupt setup */ 747 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 747 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; 748 748 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 749 749 link->irq.Handler = NULL; 750 750
+6 -2
drivers/staging/comedi/drivers/cb_pcidio.c
··· 53 53 * Some drivers use arrays such as this, other do not. 54 54 */ 55 55 struct pcidio_board { 56 - const char *name; /* anme of the board */ 56 + const char *name; /* name of the board */ 57 + int dev_id; 57 58 int n_8255; /* number of 8255 chips on board */ 58 59 59 60 /* indices of base address regions */ ··· 65 64 static const struct pcidio_board pcidio_boards[] = { 66 65 { 67 66 .name = "pci-dio24", 67 + .dev_id = 0x0028, 68 68 .n_8255 = 1, 69 69 .pcicontroler_badrindex = 1, 70 70 .dioregs_badrindex = 2, 71 71 }, 72 72 { 73 73 .name = "pci-dio24h", 74 + .dev_id = 0x0014, 74 75 .n_8255 = 1, 75 76 .pcicontroler_badrindex = 1, 76 77 .dioregs_badrindex = 2, 77 78 }, 78 79 { 79 80 .name = "pci-dio48h", 81 + .dev_id = 0x000b, 80 82 .n_8255 = 2, 81 83 .pcicontroler_badrindex = 0, 82 84 .dioregs_badrindex = 1, ··· 210 206 continue; 211 207 /* loop through cards supported by this driver */ 212 208 for (index = 0; index < ARRAY_SIZE(pcidio_boards); index++) { 213 - if (pcidio_pci_table[index].device != pcidev->device) 209 + if (pcidio_boards[index].dev_id != pcidev->device) 214 210 continue; 215 211 216 212 /* was a particular bus/slot requested? */
+6 -12
drivers/staging/comedi/drivers/jr3_pci.c
··· 515 515 { 516 516 struct poll_delay_t result = poll_delay_min_max(1000, 2000); 517 517 struct jr3_pci_subdev_private *p = s->private; 518 + int i; 518 519 519 520 if (p) { 520 521 volatile struct jr3_channel *channel = p->channel; ··· 571 570 p->serial_no); 572 571 573 572 /* Transformation all zeros */ 574 - transf.link[0].link_type = 575 - (enum link_types)0; 576 - transf.link[0].link_amount = 0; 577 - transf.link[1].link_type = 578 - (enum link_types)0; 579 - transf.link[1].link_amount = 0; 580 - transf.link[2].link_type = 581 - (enum link_types)0; 582 - transf.link[2].link_amount = 0; 583 - transf.link[3].link_type = 584 - (enum link_types)0; 585 - transf.link[3].link_amount = 0; 573 + for (i = 0; i < ARRAY_SIZE(transf.link); i++) { 574 + transf.link[i].link_type = 575 + (enum link_types)0; 576 + transf.link[i].link_amount = 0; 577 + } 586 578 587 579 set_transforms(channel, transf, 0); 588 580 use_transform(channel, 0);
+9 -3
drivers/staging/comedi/drivers/ni_65xx.c
··· 418 418 return -EINVAL; 419 419 base_bitfield_channel = CR_CHAN(insn->chanspec); 420 420 for (j = 0; j < max_ports_per_bitfield; ++j) { 421 + const unsigned port_offset = ni_65xx_port_by_channel(base_bitfield_channel) + j; 421 422 const unsigned port = 422 - sprivate(s)->base_port + 423 - ni_65xx_port_by_channel(base_bitfield_channel) + j; 423 + sprivate(s)->base_port + port_offset; 424 424 unsigned base_port_channel; 425 425 unsigned port_mask, port_data, port_read_bits; 426 426 int bitshift; 427 427 if (port >= ni_65xx_total_num_ports(board(dev))) 428 428 break; 429 - base_port_channel = port * ni_65xx_channels_per_port; 429 + base_port_channel = port_offset * ni_65xx_channels_per_port; 430 430 port_mask = data[0]; 431 431 port_data = data[1]; 432 432 bitshift = base_port_channel - base_bitfield_channel; ··· 457 457 port_read_bits = 458 458 readb(private(dev)->mite->daq_io_addr + Port_Data(port)); 459 459 /* printk("read 0x%x from port %i\n", port_read_bits, port); */ 460 + if (s->type == COMEDI_SUBD_DO && board(dev)->invert_outputs) { 461 + /* Outputs inverted, so invert value read back from 462 + * DO subdevice. (Does not apply to boards with DIO 463 + * subdevice.) */ 464 + port_read_bits ^= 0xFF; 465 + } 460 466 if (bitshift > 0) { 461 467 port_read_bits <<= bitshift; 462 468 } else {
+1 -1
drivers/staging/comedi/drivers/ni_daq_700.c
··· 520 520 link->priv = local; 521 521 522 522 /* Interrupt setup */ 523 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 523 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; 524 524 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 525 525 link->irq.Handler = NULL; 526 526
+1 -1
drivers/staging/comedi/drivers/ni_daq_dio24.c
··· 271 271 link->priv = local; 272 272 273 273 /* Interrupt setup */ 274 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 274 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; 275 275 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 276 276 link->irq.Handler = NULL; 277 277
+1 -1
drivers/staging/comedi/drivers/ni_labpc_cs.c
··· 246 246 link->priv = local; 247 247 248 248 /* Interrupt setup */ 249 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE; 249 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE; 250 250 link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID; 251 251 link->irq.Handler = NULL; 252 252
+1 -1
drivers/staging/comedi/drivers/ni_mio_cs.c
··· 273 273 { 274 274 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 275 275 link->io.NumPorts1 = 16; 276 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 276 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; 277 277 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 278 278 link->conf.Attributes = CONF_ENABLE_IRQ; 279 279 link->conf.IntType = INT_MEMORY_AND_IO;
+21 -1
drivers/staging/comedi/drivers/ni_pcimio.c
··· 29 29 PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E, 30 30 PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E, 31 31 PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E, 32 - PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, 32 + PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225, PXI-6225, 33 33 PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259, 34 34 PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289, 35 35 PCI-6711, PXI-6711, PCI-6713, PXI-6713, ··· 179 179 PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 180 180 PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 181 181 PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 182 + PCI_VENDOR_ID_NATINST, 0x716d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 182 183 PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 183 184 PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 184 185 PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { ··· 953 952 .caldac = {caldac_none}, 954 953 .has_8255 = 0, 955 954 }, 955 + { 956 + .device_id = 0x716d, 957 + .name = "pxi-6225", 958 + .n_adchan = 80, 959 + .adbits = 16, 960 + .ai_fifo_depth = 4095, 961 + .gainlkup = ai_gain_622x, 962 + .ai_speed = 4000, 963 + .n_aochan = 2, 964 + .aobits = 16, 965 + .ao_fifo_depth = 8191, 966 + .ao_range_table = &range_ni_M_622x_ao, 967 + .reg_type = ni_reg_622x, 968 + .ao_unipolar = 0, 969 + .ao_speed = 1200, 970 + .num_p0_dio_channels = 32, 971 + .caldac = {caldac_none}, 972 + .has_8255 = 0, 973 + }, 956 974 { 957 975 .device_id = 0x70aa, 958 976 .name = "pci-6229",
+1 -1
drivers/staging/comedi/drivers/quatech_daqp_cs.c
··· 1079 1079 link->priv = local; 1080 1080 1081 1081 /* Interrupt setup */ 1082 - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 1082 + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; 1083 1083 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 1084 1084 link->irq.Handler = daqp_interrupt; 1085 1085 link->irq.Instance = local;
+61 -48
drivers/staging/comedi/drivers/s526.c
··· 43 43 44 44 #include "../comedidev.h" 45 45 #include <linux/ioport.h> 46 + #include <asm/byteorder.h> 46 47 47 48 #define S526_SIZE 64 48 49 ··· 114 113 }; 115 114 116 115 struct counter_mode_register_t { 116 + #if defined (__LITTLE_ENDIAN_BITFIELD) 117 117 unsigned short coutSource:1; 118 118 unsigned short coutPolarity:1; 119 119 unsigned short autoLoadResetRcap:3; ··· 126 124 unsigned short outputRegLatchCtrl:1; 127 125 unsigned short preloadRegSel:1; 128 126 unsigned short reserved:1; 127 + #elif defined(__BIG_ENDIAN_BITFIELD) 128 + unsigned short reserved:1; 129 + unsigned short preloadRegSel:1; 130 + unsigned short outputRegLatchCtrl:1; 131 + unsigned short countDirCtrl:1; 132 + unsigned short countDir:1; 133 + unsigned short clockSource:2; 134 + unsigned short ctEnableCtrl:2; 135 + unsigned short hwCtEnableSource:2; 136 + unsigned short autoLoadResetRcap:3; 137 + unsigned short coutPolarity:1; 138 + unsigned short coutSource:1; 139 + #else 140 + #error Unknown bit field order 141 + #endif 129 142 }; 130 143 131 - union { 144 + union cmReg { 132 145 struct counter_mode_register_t reg; 133 146 unsigned short value; 134 - } cmReg; 147 + }; 135 148 136 149 #define MAX_GPCT_CONFIG_DATA 6 137 150 ··· 302 285 int i, n; 303 286 /* short value; */ 304 287 /* int subdev_channel = 0; */ 288 + union cmReg cmReg; 305 289 306 290 printk("comedi%d: s526: ", dev->minor); 307 291 ··· 393 375 if (thisboard->have_dio) { 394 376 s->type = COMEDI_SUBD_DIO; 395 377 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 396 - s->n_chan = 2; 378 + s->n_chan = 8; 397 379 s->maxdata = 1; 398 380 s->range_table = &range_digital; 399 381 s->insn_bits = s526_dio_insn_bits; ··· 453 435 udelay(1000); 454 436 printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n))); 455 437 456 - /* Load the pre-laod register high word */ 438 + /* Load the pre-load register high word */ 457 439 /* value = (short) (0x55); */ 458 440 /* outw(value, ADDR_CHAN_REG(REG_C0H, n)); */ 459 441 460 - /* Load the pre-laod register low word */ 442 + /* Load the pre-load register low word */ 461 443 /* value = (short)(0xaa55); */ 462 444 /* outw(value, ADDR_CHAN_REG(REG_C0L, n)); */ 463 445 ··· 534 516 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ 535 517 int i; 536 518 short value; 519 + union cmReg cmReg; 537 520 538 521 /* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel); */ 539 522 ··· 587 568 588 569 #if 1 589 570 /* Set Counter Mode Register */ 590 - cmReg.reg.coutSource = 0; /* out RCAP */ 591 - cmReg.reg.coutPolarity = 0; /* Polarity inverted */ 592 - cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */ 593 - cmReg.reg.hwCtEnableSource = 2; /* NOT RCAP */ 594 - cmReg.reg.ctEnableCtrl = 1; /* 1: Software, >1 : Hardware */ 595 - cmReg.reg.clockSource = 3; /* x4 */ 596 - cmReg.reg.countDir = 0; /* up */ 597 - cmReg.reg.countDirCtrl = 0; /* quadrature */ 598 - cmReg.reg.outputRegLatchCtrl = 0; /* latch on read */ 599 - cmReg.reg.preloadRegSel = 0; /* PR0 */ 600 - cmReg.reg.reserved = 0; 571 + cmReg.value = insn->data[1] & 0xFFFF; 601 572 602 - /* Set Counter Mode Register */ 603 573 /* printk("s526: Counter Mode register=%x\n", cmReg.value); */ 604 574 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 605 575 ··· 623 615 cmReg.value = (short)(insn->data[1] & 0xFFFF); 624 616 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 625 617 626 - /* Load the pre-laod register high word */ 618 + /* Load the pre-load register high word */ 627 619 value = (short)((insn->data[2] >> 16) & 0xFFFF); 628 620 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 629 621 630 - /* Load the pre-laod register low word */ 622 + /* Load the pre-load register low word */ 631 623 value = (short)(insn->data[2] & 0xFFFF); 632 624 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 633 625 ··· 661 653 cmReg.reg.preloadRegSel = 0; /* PR0 */ 662 654 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 663 655 664 - /* Load the pre-laod register 0 high word */ 656 + /* Load the pre-load register 0 high word */ 665 657 value = (short)((insn->data[2] >> 16) & 0xFFFF); 666 658 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 667 659 668 - /* Load the pre-laod register 0 low word */ 660 + /* Load the pre-load register 0 low word */ 669 661 value = (short)(insn->data[2] & 0xFFFF); 670 662 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 671 663 ··· 674 666 cmReg.reg.preloadRegSel = 1; /* PR1 */ 675 667 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 676 668 677 - /* Load the pre-laod register 1 high word */ 669 + /* Load the pre-load register 1 high word */ 678 670 value = (short)((insn->data[3] >> 16) & 0xFFFF); 679 671 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 680 672 681 - /* Load the pre-laod register 1 low word */ 673 + /* Load the pre-load register 1 low word */ 682 674 value = (short)(insn->data[3] & 0xFFFF); 683 675 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 684 676 685 677 /* Write the Counter Control Register */ 686 - if (insn->data[3] != 0) { 687 - value = (short)(insn->data[3] & 0xFFFF); 678 + if (insn->data[4] != 0) { 679 + value = (short)(insn->data[4] & 0xFFFF); 688 680 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); 689 681 } 690 682 break; ··· 706 698 cmReg.reg.preloadRegSel = 0; /* PR0 */ 707 699 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 708 700 709 - /* Load the pre-laod register 0 high word */ 701 + /* Load the pre-load register 0 high word */ 710 702 value = (short)((insn->data[2] >> 16) & 0xFFFF); 711 703 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 712 704 713 - /* Load the pre-laod register 0 low word */ 705 + /* Load the pre-load register 0 low word */ 714 706 value = (short)(insn->data[2] & 0xFFFF); 715 707 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 716 708 ··· 719 711 cmReg.reg.preloadRegSel = 1; /* PR1 */ 720 712 outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel)); 721 713 722 - /* Load the pre-laod register 1 high word */ 714 + /* Load the pre-load register 1 high word */ 723 715 value = (short)((insn->data[3] >> 16) & 0xFFFF); 724 716 outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel)); 725 717 726 - /* Load the pre-laod register 1 low word */ 718 + /* Load the pre-load register 1 low word */ 727 719 value = (short)(insn->data[3] & 0xFFFF); 728 720 outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel)); 729 721 730 722 /* Write the Counter Control Register */ 731 - if (insn->data[3] != 0) { 732 - value = (short)(insn->data[3] & 0xFFFF); 723 + if (insn->data[4] != 0) { 724 + value = (short)(insn->data[4] & 0xFFFF); 733 725 outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel)); 734 726 } 735 727 break; ··· 749 741 { 750 742 int subdev_channel = CR_CHAN(insn->chanspec); /* Unpack chanspec */ 751 743 short value; 744 + union cmReg cmReg; 752 745 753 746 printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel); 754 747 cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel)); ··· 784 775 (devpriv->s526_gpct_config[subdev_channel]).data[1] = 785 776 insn->data[1]; 786 777 } else { 787 - printk("%d \t %d\n", insn->data[1], insn->data[2]); 788 - printk 789 - ("s526: INSN_WRITE: PTG: Problem with Pulse params\n"); 778 + printk("s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n", 779 + insn->data[0], insn->data[1]); 790 780 return -EINVAL; 791 781 } 792 782 ··· 957 949 data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ 958 950 /* or we could just return the software copy of the output values if 959 951 * it was a purely digital output subdevice */ 960 - /* data[1]=s->state; */ 952 + /* data[1]=s->state & 0xFF; */ 961 953 962 954 return 2; 963 955 } ··· 967 959 struct comedi_insn *insn, unsigned int *data) 968 960 { 969 961 int chan = CR_CHAN(insn->chanspec); 970 - short value; 962 + int group, mask; 971 963 972 964 printk("S526 DIO insn_config\n"); 973 - 974 - if (insn->n != 1) 975 - return -EINVAL; 976 - 977 - value = inw(ADDR_REG(REG_DIO)); 978 965 979 966 /* The input or output configuration of each digital line is 980 967 * configured by a special insn_config instruction. chanspec 981 968 * contains the channel to be changed, and data[0] contains the 982 969 * value COMEDI_INPUT or COMEDI_OUTPUT. */ 983 970 984 - if (data[0] == COMEDI_OUTPUT) { 985 - value |= 1 << (chan + 10); /* bit 10/11 set the group 1/2's mode */ 986 - s->io_bits |= (0xF << chan); 987 - } else { 988 - value &= ~(1 << (chan + 10)); /* 1 is output, 0 is input. */ 989 - s->io_bits &= ~(0xF << chan); 971 + group = chan >> 2; 972 + mask = 0xF << (group << 2); 973 + switch (data[0]) { 974 + case INSN_CONFIG_DIO_OUTPUT: 975 + s->state |= 1 << (group + 10); // bit 10/11 set the group 1/2's mode 976 + s->io_bits |= mask; 977 + break; 978 + case INSN_CONFIG_DIO_INPUT: 979 + s->state &= ~(1 << (group + 10));// 1 is output, 0 is input. 980 + s->io_bits &= ~mask; 981 + break; 982 + case INSN_CONFIG_DIO_QUERY: 983 + data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; 984 + return insn->n; 985 + default: 986 + return -EINVAL; 990 987 } 991 - outw(value, ADDR_REG(REG_DIO)); 988 + outw(s->state, ADDR_REG(REG_DIO)); 992 989 993 990 return 1; 994 991 }
+1
drivers/staging/comedi/drivers/serial2002.c
··· 35 35 36 36 #include <linux/delay.h> 37 37 #include <linux/ioport.h> 38 + #include <linux/sched.h> 38 39 39 40 #include <asm/termios.h> 40 41 #include <asm/ioctls.h>
-16
drivers/staging/cowloop/Kconfig
··· 1 - config COWLOOP 2 - tristate "copy-on-write pseudo Block Driver" 3 - depends on BLOCK 4 - default n 5 - ---help--- 6 - Cowloop is a "copy-on-write" pseudo block driver. It can be 7 - stacked on top of a "real" block driver, and catches all write 8 - operations on their way from the file systems layer above to 9 - the real driver below, effectively shielding the lower driver 10 - from those write accesses. The requests are then diverted to 11 - an ordinary file, located somewhere else (configurable). Later 12 - read requests are checked to see whether they can be serviced 13 - by the "real" block driver below, or must be pulled in from 14 - the diverted location. More information and userspace tools to 15 - use the driver are on the project's website 16 - http://www.ATComputing.nl/cowloop/
-1
drivers/staging/cowloop/Makefile
··· 1 - obj-$(CONFIG_COWLOOP) += cowloop.o
-11
drivers/staging/cowloop/TODO
··· 1 - TODO: 2 - - checkpatch.pl cleanups 3 - - run sparse to ensure clean 4 - - fix up 32/64bit ioctl issues 5 - - move proc file usage to debugfs 6 - - audit ioctls 7 - - add documentation 8 - - get linux-fsdevel to review it 9 - 10 - Please send patches to "H.J. Thomassen" <hjt@ATComputing.nl> and 11 - Greg Kroah-Hartman <gregkh@suse.de>
-2842
drivers/staging/cowloop/cowloop.c
··· 1 - /* 2 - ** COWLOOP block device driver (2.6 kernel compliant) 3 - ** ======================================================================= 4 - ** Read-write loop-driver with copy-on-write functionality. 5 - ** 6 - ** Synopsis: 7 - ** 8 - ** modprobe cowloop [maxcows=..] [rdofile=..... cowfile=.... [option=r]] 9 - ** 10 - ** Definition of number of configured cowdevices: 11 - ** maxcows= number of configured cowdevices (default: 16) 12 - ** (do not confuse this with MAXCOWS: absolute maximum as compiled) 13 - ** 14 - ** One pair of filenames can be supplied during insmod/modprobe to open 15 - ** the first cowdevice: 16 - ** rdofile= read-only file (or filesystem) 17 - ** cowfile= storage-space for modified blocks of read-only file(system) 18 - ** option=r repair cowfile automatically if it appears to be dirty 19 - ** 20 - ** Other cowdevices can be activated via the command "cowdev" 21 - ** whenever the cowloop-driver is loaded. 22 - ** 23 - ** The read-only file may be of type 'regular' or 'block-device'. 24 - ** 25 - ** The cowfile must be of type 'regular'. 26 - ** If an existing regular file is used as cowfile, its contents will be 27 - ** used again for the current read-only file. When the cowfile has not been 28 - ** closed properly during a previous session (i.e. rmmod cowloop), the 29 - ** cowloop-driver refuses to open it unless the parameter "option=r" is 30 - ** specified. 31 - ** 32 - ** Layout of cowfile: 33 - ** 34 - ** +-----------------------------+ 35 - ** | cow head block | MAPUNIT bytes 36 - ** |-----------------------------| 37 - ** | | MAPUNIT bytes 38 - ** |--- ---| 39 - ** | | MAPUNIT bytes 40 - ** |--- ---| 41 - ** | used-block bitmap | MAPUNIT bytes 42 - ** |-----------------------------| 43 - ** | gap to align start-offset | 44 - ** | to 4K multiple | 45 - ** |-----------------------------| <---- start-offset cow blocks 46 - ** | | 47 - ** | written cow blocks | MAPUNIT bytes 48 - ** | ..... | 49 - ** 50 - ** cowhead block: 51 - ** - contains general info about the rdofile which is related 52 - ** to this cowfile 53 - ** 54 - ** used-block bitmap: 55 - ** - contains one bit per block with a size of MAPUNIT bytes 56 - ** - bit-value '1' = block has been written on cow 57 - ** '0' = block unused on cow 58 - ** - total bitmap rounded to multiples of MAPUNIT 59 - ** 60 - ** ============================================================================ 61 - ** Author: Gerlof Langeveld - AT Computing (March 2003) 62 - ** Current maintainer: Hendrik-Jan Thomassen - AT Computing (Summer 2006) 63 - ** Email: hjt@ATComputing.nl 64 - ** ---------------------------------------------------------------------------- 65 - ** Copyright (C) 2003-2009 AT Consultancy 66 - ** 67 - ** This program is free software; you can redistribute it and/or modify it 68 - ** under the terms of the GNU General Public License as published by the 69 - ** Free Software Foundation; either version 2, or (at your option) any 70 - ** later version. 71 - ** 72 - ** This program is distributed in the hope that it will be useful, but 73 - ** WITHOUT ANY WARRANTY; without even the implied warranty of 74 - ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 75 - ** See the GNU General Public License for more details. 76 - ** 77 - ** You should have received a copy of the GNU General Public License 78 - ** along with this program; if not, write to the Free Software 79 - ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 80 - ** ---------------------------------------------------------------------------- 81 - ** 82 - ** Major modifications: 83 - ** 84 - ** 200405 Ported to kernel-version 2.6 Hendrik-Jan Thomassen 85 - ** 200405 Added cowhead to cowfile to garantee 86 - ** consistency with read-only file Gerlof Langeveld 87 - ** 200405 Postponed flushing of bitmaps to improve 88 - ** performance. Gerlof Langeveld 89 - ** 200405 Inline recovery for dirty cowfiles. Gerlof Langeveld 90 - ** 200502 Redesign to support more cowdevices. Gerlof Langeveld 91 - ** 200502 Support devices/file > 2 Gbytes. Gerlof Langeveld 92 - ** 200507 Check for free space to expand cowfile. Gerlof Langeveld 93 - ** 200902 Upgrade for kernel 2.6.28 Hendrik-Jan Thomassen 94 - ** 95 - ** Inspired by 96 - ** loop.c by Theodore Ts'o and 97 - ** cloop.c by Paul `Rusty' Russell & Klaus Knopper. 98 - ** 99 - ** Design-considerations: 100 - ** 101 - ** For the first experiments with the cowloop-driver, the request-queue 102 - ** made use of the do_generic_file_read() which worked fine except 103 - ** in combination with the cloop-driver; that combination 104 - ** resulted in a non-interruptible hangup of the system during 105 - ** heavy load. Other experiments using the `make_request' interface also 106 - ** resulted in unpredictable system hangups (with proper use of spinlocks). 107 - ** 108 - ** To overcome these problems, the cowloop-driver starts a kernel-thread 109 - ** for every active cowdevice. 110 - ** All read- and write-request on the read-only file and copy-on-write file 111 - ** are handled in the context of that thread. 112 - ** A scheme has been designed to wakeup the kernel-thread as 113 - ** soon as I/O-requests are available in the request-queue; this thread 114 - ** handles the requests one-by-one by calling the proper read- or 115 - ** write-function related to the open read-only file or copy-on-write file. 116 - ** When all pending requests have been handled, the kernel-thread goes 117 - ** back to sleep-state. 118 - ** This approach requires some additional context-switches; however the 119 - ** performance loss during heavy I/O is less than 3%. 120 - ** 121 - ** -------------------------------------------------------------------------*/ 122 - /* The following is the cowloop package version number. It must be 123 - identical to the content of the include-file "version.h" that is 124 - used in all supporting utilities: */ 125 - char revision[] = "$Revision: 3.1 $"; /* cowlo_init_module() has 126 - assumptions about this string's format */ 127 - 128 - /* Note that the following numbers are *not* the cowloop package version 129 - numbers, but separate revision history numbers to track the 130 - modifications of this particular source file: */ 131 - /* $Log: cowloop.c,v $ 132 - ** 133 - ** Revision 1.30 2009/02/08 hjt 134 - ** Integrated earlier fixes 135 - ** Upgraded to kernel 2.6.28 (thanks Jerome Poulin) 136 - ** 137 - ** Revision 1.29 2006/12/03 22:12:00 hjt 138 - ** changed 'cowdevlock' from spinlock to semaphore, to avoid 139 - ** "scheduling while atomic". Contributed by Juergen Christ. 140 - ** Added version.h again 141 - ** 142 - ** Revision 1.28 2006/08/16 16:00:00 hjt 143 - ** malloc each individual cowloopdevice struct separately 144 - ** 145 - ** Revision 1.27 2006/03/14 14:57:03 root 146 - ** Removed include version.h 147 - ** 148 - ** Revision 1.26 2005/08/08 11:22:48 root 149 - ** Implement possibility to close a cow file or reopen a cowfile read-only. 150 - ** 151 - ** Revision 1.25 2005/08/03 14:00:39 root 152 - ** Added modinfo info to driver. 153 - ** 154 - ** Revision 1.24 2005/07/21 06:14:53 root 155 - ** Cosmetic changes source code. 156 - ** 157 - ** Revision 1.23 2005/07/20 13:07:32 root 158 - ** Supply ioctl to write watchdog program to react on lack of cowfile space. 159 - ** 160 - ** Revision 1.22 2005/07/20 07:53:34 root 161 - ** Regular verification of free space in filesystem holding the cowfile 162 - ** (give warnings whenever space is almost exhausted). 163 - ** Terminology change: checksum renamed to fingerprint. 164 - ** 165 - ** Revision 1.21 2005/07/19 09:21:52 root 166 - ** Removing maximum limit of 16 Gb per cowdevice. 167 - ** 168 - ** Revision 1.20 2005/07/19 07:50:33 root 169 - ** Minor bugfixes and cosmetic changes. 170 - ** 171 - ** Revision 1.19 2005/06/10 12:29:55 root 172 - ** Removed lock/unlock operation from cowlo_open(). 173 - ** 174 - ** Revision 1.18 2005/05/09 12:56:26 root 175 - ** Allow a cowdevice to be open more than once 176 - ** (needed for support of ReiserFS and XFS). 177 - ** 178 - ** Revision 1.17 2005/03/17 14:36:16 root 179 - ** Fixed some license issues. 180 - ** 181 - ** Revision 1.16 2005/03/07 14:42:05 root 182 - ** Only allow one parallel open per cowdevice. 183 - ** 184 - ** Revision 1.15 2005/02/18 11:52:04 gerlof 185 - ** Redesign to support more than one cowdevice > 2 Gb space. 186 - ** 187 - ** Revision 1.14 2004/08/17 14:19:16 gerlof 188 - ** Modified output of /proc/cowloop. 189 - ** 190 - ** Revision 1.13 2004/08/16 07:21:10 gerlof 191 - ** Separate statistical counter for read on rdofile and cowfile. 192 - ** 193 - ** Revision 1.12 2004/08/11 06:52:11 gerlof 194 - ** Modified messages. 195 - ** 196 - ** Revision 1.11 2004/08/11 06:44:11 gerlof 197 - ** Modified log messages. 198 - ** 199 - ** Revision 1.10 2004/08/10 12:27:27 gerlof 200 - ** Cosmetic changes. 201 - ** 202 - ** Revision 1.9 2004/08/09 11:43:37 gerlof 203 - ** Removed double definition of major number (COWMAJOR). 204 - ** 205 - ** Revision 1.8 2004/08/09 08:03:39 gerlof 206 - ** Cleanup of messages. 207 - ** 208 - ** Revision 1.7 2004/05/27 06:37:33 gerlof 209 - ** Modified /proc message. 210 - ** 211 - ** Revision 1.6 2004/05/26 21:23:28 gerlof 212 - ** Modified /proc output. 213 - ** 214 - ** Revision 1.5 2004/05/26 13:23:34 gerlof 215 - ** Support cowsync to force flushing the bitmaps and cowhead. 216 - ** 217 - ** Revision 1.4 2004/05/26 11:11:10 gerlof 218 - ** Updated the comment to the actual situation. 219 - ** 220 - ** Revision 1.3 2004/05/26 10:50:00 gerlof 221 - ** Implemented recovery-option. 222 - ** 223 - ** Revision 1.2 2004/05/25 15:14:41 gerlof 224 - ** Modified bitmap flushing strategy. 225 - ** 226 - */ 227 - 228 - #define COWMAJOR 241 229 - 230 - // #define COWDEBUG 231 - 232 - #ifdef COWDEBUG 233 - #define DEBUGP printk 234 - #define DCOW KERN_ALERT 235 - #else 236 - #define DEBUGP(format, x...) 237 - #endif 238 - 239 - #include <linux/types.h> 240 - #include <linux/autoconf.h> 241 - #ifndef AUTOCONF_INCLUDED 242 - #include <linux/config.h> 243 - #endif 244 - #include <linux/module.h> 245 - #include <linux/version.h> 246 - #include <linux/moduleparam.h> 247 - #include <linux/init.h> 248 - #include <linux/errno.h> 249 - #include <linux/kernel.h> 250 - #include <linux/major.h> 251 - #include <linux/sched.h> 252 - #include <linux/fs.h> 253 - #include <linux/file.h> 254 - #include <linux/stat.h> 255 - #include <linux/vmalloc.h> 256 - #include <linux/slab.h> 257 - #include <linux/semaphore.h> 258 - #include <asm/uaccess.h> 259 - #include <linux/proc_fs.h> 260 - #include <linux/blkdev.h> 261 - #include <linux/buffer_head.h> 262 - #include <linux/hdreg.h> 263 - #include <linux/genhd.h> 264 - #include <linux/statfs.h> 265 - 266 - #include "cowloop.h" 267 - 268 - MODULE_LICENSE("GPL"); 269 - /* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>"); obsolete address */ 270 - MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */ 271 - MODULE_DESCRIPTION("Copy-on-write loop driver"); 272 - MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)"); 273 - MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0"); 274 - MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0"); 275 - MODULE_PARM_DESC(option, " Repair cowfile if inconsistent: option=r"); 276 - 277 - #define DEVICE_NAME "cow" 278 - 279 - #define DFLCOWS 16 /* default cowloop devices */ 280 - 281 - static int maxcows = DFLCOWS; 282 - module_param(maxcows, int, 0); 283 - static char *rdofile = ""; 284 - module_param(rdofile, charp, 0); 285 - static char *cowfile = ""; 286 - module_param(cowfile, charp, 0); 287 - static char *option = ""; 288 - module_param(option, charp, 0); 289 - 290 - /* 291 - ** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each 292 - ** 293 - ** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data 294 - ** suppose: 295 - ** MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk 296 - */ 297 - #define MAPCHUNKSZ 4096 /* #bytes per bitmap chunk (do not change) */ 298 - 299 - #define SPCMINBLK 100 /* space threshold to give warning messages */ 300 - #define SPCDFLINTVL 16 /* once every SPCDFLINTVL writes to cowfile, */ 301 - /* available space in filesystem is checked */ 302 - 303 - #define CALCMAP(x) ((x)/(MAPCHUNKSZ*8)) 304 - #define CALCBYTE(x) (((x)%(MAPCHUNKSZ*8))>>3) 305 - #define CALCBIT(x) ((x)&7) 306 - 307 - #define ALLCOW 1 308 - #define ALLRDO 2 309 - #define MIXEDUP 3 310 - 311 - static char allzeroes[MAPUNIT]; 312 - 313 - /* 314 - ** administration per cowdevice (pair of cowfile/rdofile) 315 - */ 316 - 317 - /* bit-values for state */ 318 - #define COWDEVOPEN 0x01 /* cowdevice opened */ 319 - #define COWRWCOWOPEN 0x02 /* cowfile opened read-write */ 320 - #define COWRDCOWOPEN 0x04 /* cowfile opened read-only */ 321 - #define COWWATCHDOG 0x08 /* ioctl for watchdog cowfile space active */ 322 - 323 - #define COWCOWOPEN (COWRWCOWOPEN|COWRDCOWOPEN) 324 - 325 - struct cowloop_device 326 - { 327 - /* 328 - ** current status 329 - */ 330 - int state; /* bit-values (see above) */ 331 - int opencnt; /* # opens for cowdevice */ 332 - 333 - /* 334 - ** open file pointers 335 - */ 336 - struct file *rdofp, *cowfp; /* open file pointers */ 337 - char *rdoname, *cowname; /* file names */ 338 - 339 - /* 340 - ** request queue administration 341 - */ 342 - struct request_queue *rqueue; 343 - spinlock_t rqlock; 344 - struct gendisk *gd; 345 - 346 - /* 347 - ** administration about read-only file 348 - */ 349 - unsigned int numblocks; /* # blocks input file in MAPUNIT */ 350 - unsigned int blocksz; /* minimum unit to access this dev */ 351 - unsigned long fingerprint; /* fingerprint of current rdofile */ 352 - struct block_device *belowdev; /* block device below us */ 353 - struct gendisk *belowgd; /* gendisk for blk dev below us */ 354 - struct request_queue *belowq; /* req. queue of blk dev below us */ 355 - 356 - /* 357 - ** bitmap administration to register which blocks are modified 358 - */ 359 - long int mapsize; /* total size of bitmap (bytes) */ 360 - long int mapremain; /* remaining bytes in last bitmap */ 361 - int mapcount; /* number of bitmaps in use */ 362 - char **mapcache; /* area with pointers to bitmaps */ 363 - 364 - char *iobuf; /* databuffer of MAPUNIT bytes */ 365 - struct cowhead *cowhead; /* buffer containing cowhead */ 366 - 367 - /* 368 - ** administration for interface with the kernel-thread 369 - */ 370 - int pid; /* pid==0: no thread available */ 371 - struct request *req; /* request to be handled now */ 372 - wait_queue_head_t waitq; /* wait-Q: thread waits for work */ 373 - char closedown; /* boolean: thread exit required */ 374 - char qfilled; /* boolean: I/O request pending */ 375 - char iobusy; /* boolean: req under treatment */ 376 - 377 - /* 378 - ** administration to keep track of free space in cowfile filesystem 379 - */ 380 - unsigned long blksize; /* block size of fs (bytes) */ 381 - unsigned long blktotal; /* recent total space in fs (blocks) */ 382 - unsigned long blkavail; /* recent free space in fs (blocks) */ 383 - 384 - wait_queue_head_t watchq; /* wait-Q: watcher awaits threshold */ 385 - unsigned long watchthresh; /* threshold of watcher (blocks) */ 386 - 387 - /* 388 - ** statistical counters 389 - */ 390 - unsigned long rdoreads; /* number of read-actions rdo */ 391 - unsigned long cowreads; /* number of read-actions cow */ 392 - unsigned long cowwrites; /* number of write-actions */ 393 - unsigned long nrcowblocks; /* number of blocks in use on cow */ 394 - }; 395 - 396 - static struct cowloop_device **cowdevall; /* ptr to ptrs to all cowdevices */ 397 - static struct semaphore cowdevlock; /* generic lock for cowdevs */ 398 - 399 - static struct gendisk *cowctlgd; /* gendisk control channel */ 400 - static spinlock_t cowctlrqlock; /* for req.q. of ctrl. channel */ 401 - 402 - /* 403 - ** private directory /proc/cow 404 - */ 405 - struct proc_dir_entry *cowlo_procdir; 406 - 407 - /* 408 - ** function prototypes 409 - */ 410 - static long int cowlo_do_request (struct request *req); 411 - static void cowlo_sync (void); 412 - static int cowlo_checkio (struct cowloop_device *, int, loff_t); 413 - static int cowlo_readmix (struct cowloop_device *, void *, int, loff_t); 414 - static int cowlo_writemix (struct cowloop_device *, void *, int, loff_t); 415 - static long int cowlo_readrdo (struct cowloop_device *, void *, int, loff_t); 416 - static long int cowlo_readcow (struct cowloop_device *, void *, int, loff_t); 417 - static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t); 418 - static long int cowlo_writecow (struct cowloop_device *, void *, int, loff_t); 419 - static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t); 420 - static int cowlo_ioctl (struct block_device *, fmode_t, 421 - unsigned int, unsigned long); 422 - static int cowlo_makepair (struct cowpair __user *); 423 - static int cowlo_removepair (unsigned long __user *); 424 - static int cowlo_watch (struct cowpair __user *); 425 - static int cowlo_cowctl (unsigned long __user *, int); 426 - static int cowlo_openpair (char *, char *, int, int); 427 - static int cowlo_closepair (struct cowloop_device *); 428 - static int cowlo_openrdo (struct cowloop_device *, char *); 429 - static int cowlo_opencow (struct cowloop_device *, char *, int); 430 - static void cowlo_undo_openrdo(struct cowloop_device *); 431 - static void cowlo_undo_opencow(struct cowloop_device *); 432 - 433 - /*****************************************************************************/ 434 - /* System call handling */ 435 - /*****************************************************************************/ 436 - 437 - /* 438 - ** handle system call open()/mount() 439 - ** 440 - ** returns: 441 - ** 0 - okay 442 - ** < 0 - error value 443 - */ 444 - static int cowlo_open(struct block_device *bdev, fmode_t mode) 445 - { 446 - struct inode *inode = bdev->bd_inode; 447 - 448 - if (!inode) 449 - return -EINVAL; 450 - 451 - if (imajor(inode) != COWMAJOR) { 452 - printk(KERN_WARNING 453 - "cowloop - unexpected major %d\n", imajor(inode)); 454 - return -ENODEV; 455 - } 456 - 457 - switch (iminor(inode)) { 458 - case COWCTL: 459 - DEBUGP(DCOW"cowloop - open %d control\n", COWCTL); 460 - break; 461 - 462 - default: 463 - DEBUGP(DCOW"cowloop - open minor %d\n", iminor(inode)); 464 - 465 - if ( iminor(inode) >= maxcows ) 466 - return -ENODEV; 467 - 468 - if ( !((cowdevall[iminor(inode)])->state & COWDEVOPEN) ) 469 - return -ENODEV; 470 - 471 - (cowdevall[iminor(inode)])->opencnt++; 472 - } 473 - 474 - return 0; 475 - } 476 - 477 - /* 478 - ** handle system call close()/umount() 479 - ** 480 - ** returns: 481 - ** 0 - okay 482 - */ 483 - static int cowlo_release(struct gendisk *gd, fmode_t mode) 484 - { 485 - struct block_device *bdev; 486 - struct inode *inode; 487 - 488 - bdev = bdget_disk(gd, 0); 489 - inode = bdev->bd_inode; 490 - if (!inode) 491 - return 0; 492 - 493 - DEBUGP(DCOW"cowloop - release (close) minor %d\n", iminor(inode)); 494 - 495 - if ( iminor(inode) != COWCTL) 496 - (cowdevall[iminor(inode)])->opencnt--; 497 - 498 - return 0; 499 - } 500 - 501 - /* 502 - ** handle system call ioctl() 503 - ** 504 - ** returns: 505 - ** 0 - okay 506 - ** < 0 - error value 507 - */ 508 - static int cowlo_ioctl(struct block_device *bdev, fmode_t mode, 509 - unsigned int cmd, unsigned long arg) 510 - { 511 - struct hd_geometry geo; 512 - struct inode *inode = bdev->bd_inode; 513 - 514 - DEBUGP(DCOW "cowloop - ioctl cmd %x\n", cmd); 515 - 516 - switch ( iminor(inode) ) { 517 - 518 - /* 519 - ** allowed via control device only 520 - */ 521 - case COWCTL: 522 - switch (cmd) { 523 - /* 524 - ** write all bitmap chunks and cowheaders to cowfiles 525 - */ 526 - case COWSYNC: 527 - down(&cowdevlock); 528 - cowlo_sync(); 529 - up(&cowdevlock); 530 - return 0; 531 - 532 - /* 533 - ** open a new cowdevice (pair of rdofile/cowfile) 534 - */ 535 - case COWMKPAIR: 536 - return cowlo_makepair((void __user *)arg); 537 - 538 - /* 539 - ** close a cowdevice (pair of rdofile/cowfile) 540 - */ 541 - case COWRMPAIR: 542 - return cowlo_removepair((void __user *)arg); 543 - 544 - /* 545 - ** watch free space of filesystem containing cowfile 546 - */ 547 - case COWWATCH: 548 - return cowlo_watch((void __user *)arg); 549 - 550 - /* 551 - ** close cowfile for active device 552 - */ 553 - case COWCLOSE: 554 - return cowlo_cowctl((void __user *)arg, COWCLOSE); 555 - 556 - /* 557 - ** reopen cowfile read-only for active device 558 - */ 559 - case COWRDOPEN: 560 - return cowlo_cowctl((void __user *)arg, COWRDOPEN); 561 - 562 - default: 563 - return -EINVAL; 564 - } /* end of switch on command */ 565 - 566 - /* 567 - ** allowed for any other cowdevice 568 - */ 569 - default: 570 - switch (cmd) { 571 - /* 572 - ** HDIO_GETGEO must be supported for fdisk, etc 573 - */ 574 - case HDIO_GETGEO: 575 - geo.cylinders = 0; 576 - geo.heads = 0; 577 - geo.sectors = 0; 578 - 579 - if (copy_to_user((void __user *)arg, &geo, sizeof geo)) 580 - return -EFAULT; 581 - return 0; 582 - 583 - default: 584 - return -EINVAL; 585 - } /* end of switch on ioctl-cmd code parameter */ 586 - } /* end of switch on minor number */ 587 - } 588 - 589 - static struct block_device_operations cowlo_fops = 590 - { 591 - .owner = THIS_MODULE, 592 - .open = cowlo_open, /* called upon open */ 593 - .release = cowlo_release, /* called upon close */ 594 - .ioctl = cowlo_ioctl, /* called upon ioctl */ 595 - }; 596 - 597 - /* 598 - ** handle ioctl-command COWMKPAIR: 599 - ** open a new cowdevice (pair of rdofile/cowfile) on-the-fly 600 - ** 601 - ** returns: 602 - ** 0 - okay 603 - ** < 0 - error value 604 - */ 605 - static int 606 - cowlo_makepair(struct cowpair __user *arg) 607 - { 608 - int i, rv=0; 609 - struct cowpair cowpair; 610 - unsigned char *cowpath; 611 - unsigned char *rdopath; 612 - 613 - /* 614 - ** retrieve info about pathnames 615 - */ 616 - if ( copy_from_user(&cowpair, arg, sizeof cowpair) ) 617 - return -EFAULT; 618 - 619 - if ( (MAJOR(cowpair.device) != COWMAJOR) && (cowpair.device != ANYDEV) ) 620 - return -EINVAL; 621 - 622 - if ( (MINOR(cowpair.device) >= maxcows) && (cowpair.device != ANYDEV) ) 623 - return -EINVAL; 624 - 625 - /* 626 - ** retrieve pathname strings 627 - */ 628 - if ( (cowpair.cowflen > PATH_MAX) || (cowpair.rdoflen > PATH_MAX) ) 629 - return -ENAMETOOLONG; 630 - 631 - if ( !(cowpath = kmalloc(cowpair.cowflen+1, GFP_KERNEL)) ) 632 - return -ENOMEM; 633 - 634 - if ( copy_from_user(cowpath, (void __user *)cowpair.cowfile, 635 - cowpair.cowflen) ) { 636 - kfree(cowpath); 637 - return -EFAULT; 638 - } 639 - *(cowpath+cowpair.cowflen) = 0; 640 - 641 - if ( !(rdopath = kmalloc(cowpair.rdoflen+1, GFP_KERNEL)) ) { 642 - kfree(cowpath); 643 - return -ENOMEM; 644 - } 645 - 646 - if ( copy_from_user(rdopath, (void __user *)cowpair.rdofile, 647 - cowpair.rdoflen) ) { 648 - kfree(rdopath); 649 - kfree(cowpath); 650 - return -EFAULT; 651 - } 652 - *(rdopath+cowpair.rdoflen) = 0; 653 - 654 - /* 655 - ** open new cowdevice 656 - */ 657 - if ( cowpair.device == ANYDEV) { 658 - /* 659 - ** search first unused minor 660 - */ 661 - for (i=0, rv=-EBUSY; i < maxcows; i++) { 662 - if ( !((cowdevall[i])->state & COWDEVOPEN) ) { 663 - rv = cowlo_openpair(rdopath, cowpath, 0, i); 664 - break; 665 - } 666 - } 667 - 668 - if (rv) { /* open failed? */ 669 - kfree(rdopath); 670 - kfree(cowpath); 671 - return rv; 672 - } 673 - 674 - /* 675 - ** return newly allocated cowdevice to user space 676 - */ 677 - cowpair.device = MKDEV(COWMAJOR, i); 678 - 679 - if ( copy_to_user(arg, &cowpair, sizeof cowpair)) { 680 - kfree(rdopath); 681 - kfree(cowpath); 682 - return -EFAULT; 683 - } 684 - } else { /* specific minor requested */ 685 - if ( (rv = cowlo_openpair(rdopath, cowpath, 0, 686 - MINOR(cowpair.device)))) { 687 - kfree(rdopath); 688 - kfree(cowpath); 689 - return rv; 690 - } 691 - } 692 - 693 - return 0; 694 - } 695 - 696 - /* 697 - ** handle ioctl-command COWRMPAIR: 698 - ** deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly 699 - ** 700 - ** returns: 701 - ** 0 - okay 702 - ** < 0 - error value 703 - */ 704 - static int 705 - cowlo_removepair(unsigned long __user *arg) 706 - { 707 - unsigned long cowdevice; 708 - struct cowloop_device *cowdev; 709 - 710 - /* 711 - ** retrieve info about device to be removed 712 - */ 713 - if ( copy_from_user(&cowdevice, arg, sizeof cowdevice)) 714 - return -EFAULT; 715 - 716 - /* 717 - ** verify major-minor number 718 - */ 719 - if ( MAJOR(cowdevice) != COWMAJOR) 720 - return -EINVAL; 721 - 722 - if ( MINOR(cowdevice) >= maxcows) 723 - return -EINVAL; 724 - 725 - cowdev = cowdevall[MINOR(cowdevice)]; 726 - 727 - if ( !(cowdev->state & COWDEVOPEN) ) 728 - return -ENODEV; 729 - 730 - /* 731 - ** synchronize bitmaps and close cowdevice 732 - */ 733 - if (cowdev->state & COWRWCOWOPEN) { 734 - down(&cowdevlock); 735 - cowlo_sync(); 736 - up(&cowdevlock); 737 - } 738 - 739 - return cowlo_closepair(cowdev); 740 - } 741 - 742 - /* 743 - ** handle ioctl-command COWWATCH: 744 - ** watch the free space of the filesystem containing a cowfile 745 - ** of an open cowdevice 746 - ** 747 - ** returns: 748 - ** 0 - okay 749 - ** < 0 - error value 750 - */ 751 - static int 752 - cowlo_watch(struct cowpair __user *arg) 753 - { 754 - struct cowloop_device *cowdev; 755 - struct cowwatch cowwatch; 756 - 757 - /* 758 - ** retrieve structure holding info 759 - */ 760 - if ( copy_from_user(&cowwatch, arg, sizeof cowwatch)) 761 - return -EFAULT; 762 - 763 - /* 764 - ** verify if cowdevice exists and is currently open 765 - */ 766 - if ( MINOR(cowwatch.device) >= maxcows) 767 - return -EINVAL; 768 - 769 - cowdev = cowdevall[MINOR(cowwatch.device)]; 770 - 771 - if ( !(cowdev->state & COWDEVOPEN) ) 772 - return -ENODEV; 773 - 774 - /* 775 - ** if the WATCHWAIT-option is set, wait until the indicated 776 - ** threshold is reached (only one waiter allowed) 777 - */ 778 - if (cowwatch.flags & WATCHWAIT) { 779 - /* 780 - ** check if already another waiter active 781 - ** for this cowdevice 782 - */ 783 - if (cowdev->state & COWWATCHDOG) 784 - return -EAGAIN; 785 - 786 - cowdev->state |= COWWATCHDOG; 787 - 788 - cowdev->watchthresh = (unsigned long long) 789 - cowwatch.threshold / 790 - (cowdev->blksize / 1024); 791 - 792 - if (wait_event_interruptible(cowdev->watchq, 793 - cowdev->watchthresh >= cowdev->blkavail)) { 794 - cowdev->state &= ~COWWATCHDOG; 795 - return EINTR; 796 - } 797 - 798 - cowdev->state &= ~COWWATCHDOG; 799 - } 800 - 801 - cowwatch.totalkb = (unsigned long long)cowdev->blktotal * 802 - cowdev->blksize / 1024; 803 - cowwatch.availkb = (unsigned long long)cowdev->blkavail * 804 - cowdev->blksize / 1024; 805 - 806 - if ( copy_to_user(arg, &cowwatch, sizeof cowwatch)) 807 - return -EFAULT; 808 - 809 - return 0; 810 - } 811 - 812 - /* 813 - ** handle ioctl-commands COWCLOSE and COWRDOPEN: 814 - ** COWCLOSE - close the cowfile while the cowdevice remains open; 815 - ** this allows an unmount of the filesystem on which 816 - ** the cowfile resides 817 - ** COWRDOPEN - close the cowfile and reopen it for read-only; 818 - ** this allows a remount read-ony of the filesystem 819 - ** on which the cowfile resides 820 - ** 821 - ** returns: 822 - ** 0 - okay 823 - ** < 0 - error value 824 - */ 825 - static int 826 - cowlo_cowctl(unsigned long __user *arg, int cmd) 827 - { 828 - struct cowloop_device *cowdev; 829 - unsigned long cowdevice; 830 - 831 - /* 832 - ** retrieve info about device to be removed 833 - */ 834 - if ( copy_from_user(&cowdevice, arg, sizeof cowdevice)) 835 - return -EFAULT; 836 - 837 - /* 838 - ** verify major-minor number 839 - */ 840 - if ( MAJOR(cowdevice) != COWMAJOR) 841 - return -EINVAL; 842 - 843 - if ( MINOR(cowdevice) >= maxcows) 844 - return -EINVAL; 845 - 846 - cowdev = cowdevall[MINOR(cowdevice)]; 847 - 848 - if ( !(cowdev->state & COWDEVOPEN) ) 849 - return -ENODEV; 850 - 851 - /* 852 - ** synchronize bitmaps and close cowfile 853 - */ 854 - if (cowdev->state & COWRWCOWOPEN) { 855 - down(&cowdevlock); 856 - cowlo_sync(); 857 - up(&cowdevlock); 858 - } 859 - 860 - /* 861 - ** handle specific ioctl-command 862 - */ 863 - switch (cmd) { 864 - case COWRDOPEN: 865 - /* 866 - ** if the cowfile is still opened read-write 867 - */ 868 - if (cowdev->state & COWRWCOWOPEN) { 869 - /* 870 - ** close the cowfile 871 - */ 872 - if (cowdev->cowfp) 873 - filp_close(cowdev->cowfp, 0); 874 - 875 - cowdev->state &= ~COWRWCOWOPEN; 876 - 877 - /* 878 - ** open again for read-only 879 - */ 880 - cowdev->cowfp = filp_open(cowdev->cowname, 881 - O_RDONLY|O_LARGEFILE, 0600); 882 - 883 - if ( (cowdev->cowfp == NULL) || IS_ERR(cowdev->cowfp) ) { 884 - printk(KERN_ERR 885 - "cowloop - failed to reopen cowfile %s\n", 886 - cowdev->cowname); 887 - return -EINVAL; 888 - } 889 - 890 - /* 891 - ** mark cowfile open for read-only 892 - */ 893 - cowdev->state |= COWRDCOWOPEN; 894 - } else { 895 - return -EINVAL; 896 - } 897 - break; 898 - 899 - case COWCLOSE: 900 - /* 901 - ** if the cowfile is still open 902 - */ 903 - if (cowdev->state & COWCOWOPEN) { 904 - /* 905 - ** close the cowfile 906 - */ 907 - if (cowdev->cowfp) 908 - filp_close(cowdev->cowfp, 0); 909 - 910 - cowdev->state &= ~COWCOWOPEN; 911 - } 912 - } 913 - 914 - return 0; 915 - } 916 - 917 - 918 - /*****************************************************************************/ 919 - /* Handling of I/O-requests for a cowdevice */ 920 - /*****************************************************************************/ 921 - 922 - /* 923 - ** function to be called by core-kernel to handle the I/O-requests 924 - ** in the queue 925 - */ 926 - static void cowlo_request(struct request_queue *q) 927 - { 928 - struct request *req; 929 - struct cowloop_device *cowdev; 930 - 931 - DEBUGP(DCOW "cowloop - request function called....\n"); 932 - 933 - while((req = blk_peek_request(q)) != NULL) { 934 - DEBUGP(DCOW "cowloop - got next request\n"); 935 - 936 - if (! blk_fs_request(req)) { 937 - /* this is not a normal file system request */ 938 - __blk_end_request_cur(req, -EIO); 939 - continue; 940 - } 941 - cowdev = req->rq_disk->private_data; 942 - 943 - if (cowdev->iobusy) 944 - return; 945 - else 946 - cowdev->iobusy = 1; 947 - 948 - /* 949 - ** when no kernel-thread is available, the request will 950 - ** produce an I/O-error 951 - */ 952 - if (!cowdev->pid) { 953 - printk(KERN_ERR"cowloop - no thread available\n"); 954 - __blk_end_request_cur(req, -EIO); /* request failed */ 955 - cowdev->iobusy = 0; 956 - continue; 957 - } 958 - 959 - /* 960 - ** handle I/O-request in the context of the kernel-thread 961 - */ 962 - cowdev->req = req; 963 - cowdev->qfilled = 1; 964 - 965 - wake_up_interruptible_sync(&cowdev->waitq); 966 - 967 - /* 968 - ** get out of this function now while the I/O-request is 969 - ** under treatment of the kernel-thread; this function 970 - ** will be called again after the current I/O-request has 971 - ** been finished by the thread 972 - */ 973 - return; 974 - } 975 - } 976 - 977 - /* 978 - ** daemon-process (kernel-thread) executes this function 979 - */ 980 - static int 981 - cowlo_daemon(struct cowloop_device *cowdev) 982 - { 983 - int rv; 984 - int minor; 985 - char myname[16]; 986 - 987 - for (minor = 0; minor < maxcows; minor++) { 988 - if (cowdev == cowdevall[minor]) break; 989 - } 990 - sprintf(myname, "cowloopd%d", minor); 991 - 992 - daemonize(myname); 993 - 994 - while (!cowdev->closedown) { 995 - /* 996 - ** sleep while waiting for an I/O request; 997 - ** note that no non-interruptible wait has been used 998 - ** because the non-interruptible version of 999 - ** a *synchronous* wake_up does not exist (any more) 1000 - */ 1001 - if (wait_event_interruptible(cowdev->waitq, cowdev->qfilled)){ 1002 - flush_signals(current); /* ignore signal-based wakeup */ 1003 - continue; 1004 - } 1005 - 1006 - if (cowdev->closedown) /* module will be unloaded ? */{ 1007 - cowdev->pid = 0; 1008 - return 0; 1009 - } 1010 - 1011 - /* 1012 - ** woken up by the I/O-request handler: treat requested I/O 1013 - */ 1014 - cowdev->qfilled = 0; 1015 - 1016 - rv = cowlo_do_request(cowdev->req); 1017 - 1018 - /* 1019 - ** reacquire the queue-spinlock for manipulating 1020 - ** the request-queue and dequeue the request 1021 - */ 1022 - spin_lock_irq(&cowdev->rqlock); 1023 - 1024 - __blk_end_request_cur(cowdev->req, rv); 1025 - cowdev->iobusy = 0; 1026 - 1027 - /* 1028 - ** initiate the next request from the queue 1029 - */ 1030 - cowlo_request(cowdev->rqueue); 1031 - 1032 - spin_unlock_irq(&cowdev->rqlock); 1033 - } 1034 - return 0; 1035 - } 1036 - 1037 - /* 1038 - ** function to be called in the context of the kernel thread 1039 - ** to handle the queued I/O-requests 1040 - ** 1041 - ** returns: 1042 - ** 0 - fail 1043 - ** 1 - success 1044 - */ 1045 - static long int 1046 - cowlo_do_request(struct request *req) 1047 - { 1048 - unsigned long len; 1049 - long int rv; 1050 - loff_t offset; 1051 - struct cowloop_device *cowdev = req->rq_disk->private_data; 1052 - 1053 - /* 1054 - ** calculate some variables which are needed later on 1055 - */ 1056 - len = blk_rq_cur_sectors(req) << 9; 1057 - offset = (loff_t) blk_rq_pos(req) << 9; 1058 - 1059 - DEBUGP(DCOW"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n", 1060 - *(req->cmd), offset, len, req->buffer); 1061 - 1062 - /* 1063 - ** handle READ- or WRITE-request 1064 - */ 1065 - switch (rq_data_dir(req)) { 1066 - /**********************************************************/ 1067 - case READ: 1068 - switch ( cowlo_checkio(cowdev, len, offset) ) { 1069 - case ALLCOW: 1070 - rv = cowlo_readcow(cowdev, req->buffer, len, offset); 1071 - break; 1072 - 1073 - case ALLRDO: 1074 - rv = cowlo_readrdo(cowdev, req->buffer, len, offset); 1075 - break; 1076 - 1077 - case MIXEDUP: 1078 - rv = cowlo_readmix(cowdev, req->buffer, len, offset); 1079 - break; 1080 - 1081 - default: 1082 - rv = 0; /* never happens */ 1083 - } 1084 - break; 1085 - 1086 - /**********************************************************/ 1087 - case WRITE: 1088 - switch ( cowlo_checkio(cowdev, len, offset) ) { 1089 - case ALLCOW: 1090 - /* 1091 - ** straight-forward write will do... 1092 - */ 1093 - DEBUGP(DCOW"cowloop - write straight "); 1094 - 1095 - rv = cowlo_writecow(cowdev, req->buffer, len, offset); 1096 - break; /* from switch */ 1097 - 1098 - case ALLRDO: 1099 - if ( (len & MUMASK) == 0) { 1100 - DEBUGP(DCOW"cowloop - write straight "); 1101 - 1102 - rv = cowlo_writecow(cowdev, req->buffer, 1103 - len, offset); 1104 - break; 1105 - } 1106 - 1107 - case MIXEDUP: 1108 - rv = cowlo_writemix(cowdev, req->buffer, len, offset); 1109 - break; 1110 - 1111 - default: 1112 - rv = 0; /* never happens */ 1113 - } 1114 - break; 1115 - 1116 - default: 1117 - printk(KERN_ERR 1118 - "cowloop - unrecognized command %d\n", *(req->cmd)); 1119 - rv = 0; 1120 - } 1121 - 1122 - return (rv <= 0 ? 0 : 1); 1123 - } 1124 - 1125 - /* 1126 - ** check for a given I/O-request if all underlying blocks 1127 - ** (with size MAPUNIT) are either in the read-only file or in 1128 - ** the cowfile (or a combination of the two) 1129 - ** 1130 - ** returns: 1131 - ** ALLRDO - all underlying blocks in rdofile 1132 - ** ALLCOW - all underlying blocks in cowfile 1133 - ** MIXEDUP - underlying blocks partly in rdofile and partly in cowfile 1134 - */ 1135 - static int 1136 - cowlo_checkio(struct cowloop_device *cowdev, int len, loff_t offset) 1137 - { 1138 - unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1139 - long int totcnt, cowcnt; 1140 - char *mc; 1141 - 1142 - /* 1143 - ** notice that the requested block might cross 1144 - ** a blocksize boundary while one of the concerned 1145 - ** blocks resides in the read-only file and another 1146 - ** one in the copy-on-write file; in that case the 1147 - ** request will be broken up into pieces 1148 - */ 1149 - if ( (len <= MAPUNIT) && 1150 - (MAPUNIT - (offset & MUMASK) <= len) ) { 1151 - /* 1152 - ** easy situation: 1153 - ** requested data-block entirely fits within 1154 - ** the mapunit used for the bitmap 1155 - ** check if that block is located in rdofile or 1156 - ** cowfile 1157 - */ 1158 - blocknr = offset >> MUSHIFT; 1159 - 1160 - mapnum = CALCMAP (blocknr); 1161 - bytenum = CALCBYTE(blocknr); 1162 - bitnum = CALCBIT (blocknr); 1163 - 1164 - if (*(*(cowdev->mapcache+mapnum)+bytenum)&(1<<bitnum)) 1165 - return ALLCOW; 1166 - else 1167 - return ALLRDO; 1168 - } 1169 - 1170 - /* 1171 - ** less easy situation: 1172 - ** the requested data-block does not fit within the mapunit 1173 - ** used for the bitmap 1174 - ** check if *all* underlying blocks involved reside on the rdofile 1175 - ** or the cowfile (so still no breakup required) 1176 - */ 1177 - for (cowcnt=totcnt=0; len > 0; len-=partlen, offset+=partlen, totcnt++){ 1178 - /* 1179 - ** calculate blocknr of involved block 1180 - */ 1181 - blocknr = offset >> MUSHIFT; 1182 - 1183 - /* 1184 - ** calculate partial length for this transfer 1185 - */ 1186 - partlen = MAPUNIT - (offset & MUMASK); 1187 - if (partlen > len) 1188 - partlen = len; 1189 - 1190 - /* 1191 - ** is this block located in the cowfile 1192 - */ 1193 - mapnum = CALCMAP (blocknr); 1194 - bytenum = CALCBYTE(blocknr); 1195 - bitnum = CALCBIT (blocknr); 1196 - 1197 - mc = *(cowdev->mapcache+mapnum); 1198 - 1199 - if (*(mc+bytenum)&(1<<bitnum)) 1200 - cowcnt++;; 1201 - 1202 - DEBUGP(DCOW 1203 - "cowloop - check %lu - map %lu, byte %lu, bit %lu, " 1204 - "cowcnt %ld, totcnt %ld %02x %p\n", 1205 - blocknr, mapnum, bytenum, bitnum, cowcnt, totcnt, 1206 - *(mc+bytenum), mc); 1207 - } 1208 - 1209 - if (cowcnt == 0) /* all involved blocks on rdofile? */ 1210 - return ALLRDO; 1211 - 1212 - if (cowcnt == totcnt) /* all involved blocks on cowfile? */ 1213 - return ALLCOW; 1214 - 1215 - /* 1216 - ** situation somewhat more complicated: 1217 - ** involved underlying blocks spread over both files 1218 - */ 1219 - return MIXEDUP; 1220 - } 1221 - 1222 - /* 1223 - ** read requested chunk partly from rdofile and partly from cowfile 1224 - ** 1225 - ** returns: 1226 - ** 0 - fail 1227 - ** 1 - success 1228 - */ 1229 - static int 1230 - cowlo_readmix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1231 - { 1232 - unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1233 - long int rv; 1234 - char *mc; 1235 - 1236 - /* 1237 - ** complicated approach: breakup required of read-request 1238 - */ 1239 - for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) { 1240 - /* 1241 - ** calculate blocknr of entire block 1242 - */ 1243 - blocknr = offset >> MUSHIFT; 1244 - 1245 - /* 1246 - ** calculate partial length for this transfer 1247 - */ 1248 - partlen = MAPUNIT - (offset & MUMASK); 1249 - if (partlen > len) 1250 - partlen = len; 1251 - 1252 - /* 1253 - ** is this block located in the cowfile 1254 - */ 1255 - mapnum = CALCMAP (blocknr); 1256 - bytenum = CALCBYTE(blocknr); 1257 - bitnum = CALCBIT (blocknr); 1258 - mc = *(cowdev->mapcache+mapnum); 1259 - 1260 - if (*(mc+bytenum)&(1<<bitnum)) { 1261 - /* 1262 - ** read (partial) block from cowfile 1263 - */ 1264 - DEBUGP(DCOW"cowloop - split read " 1265 - "cow partlen=%ld off=%lld\n", partlen, offset); 1266 - 1267 - if (cowlo_readcow(cowdev, buf, partlen, offset) <= 0) 1268 - rv = 0; 1269 - } else { 1270 - /* 1271 - ** read (partial) block from rdofile 1272 - */ 1273 - DEBUGP(DCOW"cowloop - split read " 1274 - "rdo partlen=%ld off=%lld\n", partlen, offset); 1275 - 1276 - if (cowlo_readrdo(cowdev, buf, partlen, offset) <= 0) 1277 - rv = 0; 1278 - } 1279 - } 1280 - 1281 - return rv; 1282 - } 1283 - 1284 - /* 1285 - ** chunk to be written to the cowfile needs pieces to be 1286 - ** read from the rdofile 1287 - ** 1288 - ** returns: 1289 - ** 0 - fail 1290 - ** 1 - success 1291 - */ 1292 - static int 1293 - cowlo_writemix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1294 - { 1295 - unsigned long mapnum, bytenum, bitnum, blocknr, partlen; 1296 - long int rv; 1297 - char *mc; 1298 - 1299 - /* 1300 - ** somewhat more complicated stuff is required: 1301 - ** if the request is larger than one underlying 1302 - ** block or is spread over two underlying blocks, 1303 - ** split the request into pieces; if a block does not 1304 - ** start at a block boundary, take care that 1305 - ** surrounding data is read first (if needed), 1306 - ** fit the new data in and write it as a full block 1307 - */ 1308 - for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) { 1309 - /* 1310 - ** calculate partial length for this transfer 1311 - */ 1312 - partlen = MAPUNIT - (offset & MUMASK); 1313 - if (partlen > len) 1314 - partlen = len; 1315 - 1316 - /* 1317 - ** calculate blocknr of entire block 1318 - */ 1319 - blocknr = offset >> MUSHIFT; 1320 - 1321 - /* 1322 - ** has this block been written before? 1323 - */ 1324 - mapnum = CALCMAP (blocknr); 1325 - bytenum = CALCBYTE(blocknr); 1326 - bitnum = CALCBIT (blocknr); 1327 - mc = *(cowdev->mapcache+mapnum); 1328 - 1329 - if (*(mc+bytenum)&(1<<bitnum)) { 1330 - /* 1331 - ** block has been written before; 1332 - ** write transparantly to cowfile 1333 - */ 1334 - DEBUGP(DCOW 1335 - "cowloop - splitwr transp\n"); 1336 - 1337 - if (cowlo_writecow(cowdev, buf, partlen, offset) <= 0) 1338 - rv = 0; 1339 - } else { 1340 - /* 1341 - ** block has never been written before, 1342 - ** so read entire block from 1343 - ** read-only file first, unless 1344 - ** a full block is requested to 1345 - ** be written 1346 - */ 1347 - if (partlen < MAPUNIT) { 1348 - if (cowlo_readrdo(cowdev, cowdev->iobuf, 1349 - MAPUNIT, (loff_t)blocknr << MUSHIFT) <= 0) 1350 - rv = 0; 1351 - } 1352 - 1353 - /* 1354 - ** transfer modified part into 1355 - ** the block just read 1356 - */ 1357 - memcpy(cowdev->iobuf + (offset & MUMASK), buf, partlen); 1358 - 1359 - /* 1360 - ** write entire block to cowfile 1361 - */ 1362 - DEBUGP(DCOW"cowloop - split " 1363 - "partlen=%ld off=%lld\n", 1364 - partlen, (loff_t)blocknr << MUSHIFT); 1365 - 1366 - if (cowlo_writecow(cowdev, cowdev->iobuf, MAPUNIT, 1367 - (loff_t)blocknr << MUSHIFT) <= 0) 1368 - rv = 0; 1369 - } 1370 - } 1371 - 1372 - return rv; 1373 - } 1374 - 1375 - /*****************************************************************************/ 1376 - /* I/O-support for read-only file and copy-on-write file */ 1377 - /*****************************************************************************/ 1378 - 1379 - /* 1380 - ** read data from the read-only file 1381 - ** 1382 - ** return-value: similar to user-mode read 1383 - */ 1384 - static long int 1385 - cowlo_readrdo(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1386 - { 1387 - long int rv; 1388 - mm_segment_t old_fs; 1389 - loff_t saveoffset = offset; 1390 - 1391 - DEBUGP(DCOW"cowloop - readrdo called\n"); 1392 - 1393 - old_fs = get_fs(); 1394 - set_fs( get_ds() ); 1395 - rv = cowdev->rdofp->f_op->read(cowdev->rdofp, buf, len, &offset); 1396 - set_fs(old_fs); 1397 - 1398 - if (rv < len) { 1399 - printk(KERN_WARNING "cowloop - read-failure %ld on rdofile" 1400 - "- offset=%lld len=%d\n", 1401 - rv, saveoffset, len); 1402 - } 1403 - 1404 - cowdev->rdoreads++; 1405 - return rv; 1406 - } 1407 - 1408 - /* 1409 - ** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead 1410 - ** 1411 - ** return-value: similar to user-mode read 1412 - */ 1413 - static long int 1414 - cowlo_readcow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1415 - { 1416 - DEBUGP(DCOW"cowloop - readcow called\n"); 1417 - 1418 - offset += cowdev->cowhead->doffset; 1419 - 1420 - return cowlo_readcowraw(cowdev, buf, len, offset); 1421 - } 1422 - 1423 - /* 1424 - ** read cowfile from an absolute offset 1425 - ** 1426 - ** return-value: similar to user-mode read 1427 - */ 1428 - static long int 1429 - cowlo_readcowraw(struct cowloop_device *cowdev, 1430 - void *buf, int len, loff_t offset) 1431 - { 1432 - long int rv; 1433 - mm_segment_t old_fs; 1434 - loff_t saveoffset = offset; 1435 - 1436 - DEBUGP(DCOW"cowloop - readcowraw called\n"); 1437 - 1438 - /* 1439 - ** be sure that cowfile is opened for read-write 1440 - */ 1441 - if ( !(cowdev->state & COWCOWOPEN) ) { 1442 - printk(KERN_WARNING 1443 - "cowloop - read request from cowfile refused\n"); 1444 - 1445 - return -EBADF; 1446 - } 1447 - 1448 - /* 1449 - ** issue low level read 1450 - */ 1451 - old_fs = get_fs(); 1452 - set_fs( get_ds() ); 1453 - rv = cowdev->cowfp->f_op->read(cowdev->cowfp, buf, len, &offset); 1454 - set_fs(old_fs); 1455 - 1456 - if (rv < len) { 1457 - printk(KERN_WARNING 1458 - "cowloop - read-failure %ld on cowfile" 1459 - "- offset=%lld len=%d\n", rv, saveoffset, len); 1460 - } 1461 - 1462 - cowdev->cowreads++; 1463 - return rv; 1464 - } 1465 - 1466 - /* 1467 - ** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead 1468 - ** 1469 - ** if a block is written for the first time while its contents consists 1470 - ** of binary zeroes only, the concerning bitmap is flushed to the cowfile 1471 - ** 1472 - ** return-value: similar to user-mode write 1473 - */ 1474 - static long int 1475 - cowlo_writecow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset) 1476 - { 1477 - long int rv; 1478 - unsigned long mapnum=0, mapbyte=0, mapbit=0, cowblock=0, partlen; 1479 - char *tmpptr, *mapptr = NULL; 1480 - loff_t tmpoffset, mapoffset = 0; 1481 - 1482 - DEBUGP(DCOW"cowloop - writecow called\n"); 1483 - 1484 - /* 1485 - ** be sure that cowfile is opened for read-write 1486 - */ 1487 - if ( !(cowdev->state & COWRWCOWOPEN) ) { 1488 - printk(KERN_WARNING 1489 - "cowloop - Write request to cowfile refused\n"); 1490 - 1491 - return -EBADF; 1492 - } 1493 - 1494 - /* 1495 - ** write the entire block to the cowfile 1496 - */ 1497 - tmpoffset = offset + cowdev->cowhead->doffset; 1498 - 1499 - rv = cowlo_writecowraw(cowdev, buf, len, tmpoffset); 1500 - 1501 - /* 1502 - ** verify if enough space available on filesystem holding 1503 - ** the cowfile 1504 - ** - when the last write failed (might be caused by lack of space) 1505 - ** - when a watcher is active (to react adequatly) 1506 - ** - when the previous check indicated fs was almost full 1507 - ** - with regular intervals 1508 - */ 1509 - if ( (rv <= 0) || 1510 - (cowdev->state & COWWATCHDOG) || 1511 - (cowdev->blkavail / 2 < SPCDFLINTVL) || 1512 - (cowdev->cowwrites % SPCDFLINTVL == 0) ) { 1513 - struct kstatfs ks; 1514 - 1515 - if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){ 1516 - if (ks.f_bavail <= SPCMINBLK) { 1517 - switch (ks.f_bavail) { 1518 - case 0: 1519 - case 1: 1520 - case 2: 1521 - case 3: 1522 - printk(KERN_ALERT 1523 - "cowloop - " 1524 - "ALERT: cowfile full!\n"); 1525 - break; 1526 - 1527 - default: 1528 - printk(KERN_WARNING 1529 - "cowloop - cowfile almost " 1530 - "full (only %llu Kb free)\n", 1531 - (unsigned long long) 1532 - ks.f_bsize * ks.f_bavail /1024); 1533 - } 1534 - } 1535 - 1536 - cowdev->blktotal = ks.f_blocks; 1537 - cowdev->blkavail = ks.f_bavail; 1538 - 1539 - /* 1540 - ** wakeup watcher if threshold has been reached 1541 - */ 1542 - if ( (cowdev->state & COWWATCHDOG) && 1543 - (cowdev->watchthresh >= cowdev->blkavail) ) { 1544 - wake_up_interruptible(&cowdev->watchq); 1545 - } 1546 - } 1547 - } 1548 - 1549 - if (rv <= 0) 1550 - return rv; 1551 - 1552 - DEBUGP(DCOW"cowloop - block written\n"); 1553 - 1554 - /* 1555 - ** check if block(s) is/are written to the cowfile 1556 - ** for the first time; if so, adapt the bitmap 1557 - */ 1558 - for (; len > 0; len-=partlen, offset+=partlen, buf+=partlen) { 1559 - /* 1560 - ** calculate partial length for this transfer 1561 - */ 1562 - partlen = MAPUNIT - (offset & MUMASK); 1563 - if (partlen > len) 1564 - partlen = len; 1565 - 1566 - /* 1567 - ** calculate bitnr of written chunk of cowblock 1568 - */ 1569 - cowblock = offset >> MUSHIFT; 1570 - 1571 - mapnum = CALCMAP (cowblock); 1572 - mapbyte = CALCBYTE(cowblock); 1573 - mapbit = CALCBIT (cowblock); 1574 - 1575 - if (*(*(cowdev->mapcache+mapnum)+mapbyte) & (1<<mapbit)) 1576 - continue; /* already written before */ 1577 - 1578 - /* 1579 - ** if the block is written for the first time, 1580 - ** the corresponding bit should be set in the bitmap 1581 - */ 1582 - *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit); 1583 - 1584 - cowdev->nrcowblocks++; 1585 - 1586 - DEBUGP(DCOW"cowloop - bitupdate blk=%ld map=%ld " 1587 - "byte=%ld bit=%ld\n", 1588 - cowblock, mapnum, mapbyte, mapbit); 1589 - 1590 - /* 1591 - ** check if the cowhead in the cowfile is currently 1592 - ** marked clean; if so, mark it dirty and flush it 1593 - */ 1594 - if ( !(cowdev->cowhead->flags &= COWDIRTY)) { 1595 - cowdev->cowhead->flags |= COWDIRTY; 1596 - 1597 - cowlo_writecowraw(cowdev, cowdev->cowhead, 1598 - MAPUNIT, (loff_t)0); 1599 - } 1600 - 1601 - /* 1602 - ** if the written datablock contained binary zeroes, 1603 - ** the bitmap block should be marked to be flushed to disk 1604 - ** (blocks containing all zeroes cannot be recovered by 1605 - ** the cowrepair-program later on if cowloop is not properly 1606 - ** removed via rmmod) 1607 - */ 1608 - if ( memcmp(buf, allzeroes, partlen) ) /* not all zeroes? */ 1609 - continue; /* no flush needed */ 1610 - 1611 - /* 1612 - ** calculate positions of bitmap block to be flushed 1613 - ** - pointer of bitmap block in memory 1614 - ** - offset of bitmap block in cowfile 1615 - */ 1616 - tmpptr = *(cowdev->mapcache+mapnum) + (mapbyte & (~MUMASK)); 1617 - tmpoffset = (loff_t) MAPUNIT + mapnum * MAPCHUNKSZ + 1618 - (mapbyte & (~MUMASK)); 1619 - 1620 - /* 1621 - ** flush a bitmap block at the moment that all bits have 1622 - ** been set in that block, i.e. at the moment that we 1623 - ** switch to another bitmap block 1624 - */ 1625 - if ( (mapoffset != 0) && (mapoffset != tmpoffset) ) { 1626 - if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, 1627 - mapoffset) < 0) { 1628 - printk(KERN_WARNING 1629 - "cowloop - write-failure on bitmap - " 1630 - "blk=%ld map=%ld byte=%ld bit=%ld\n", 1631 - cowblock, mapnum, mapbyte, mapbit); 1632 - } 1633 - 1634 - DEBUGP(DCOW"cowloop - bitmap blk written %lld\n", 1635 - mapoffset); 1636 - } 1637 - 1638 - /* 1639 - ** remember offset in cowfile and offset in memory 1640 - ** for bitmap to be flushed; flushing will be done 1641 - ** as soon as all updates in this bitmap block have 1642 - ** been done 1643 - */ 1644 - mapoffset = tmpoffset; 1645 - mapptr = tmpptr; 1646 - } 1647 - 1648 - /* 1649 - ** any new block written containing binary zeroes? 1650 - */ 1651 - if (mapoffset) { 1652 - if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, mapoffset) < 0) { 1653 - printk(KERN_WARNING 1654 - "cowloop - write-failure on bitmap - " 1655 - "blk=%ld map=%ld byte=%ld bit=%ld\n", 1656 - cowblock, mapnum, mapbyte, mapbit); 1657 - } 1658 - 1659 - DEBUGP(DCOW"cowloop - bitmap block written %lld\n", mapoffset); 1660 - } 1661 - 1662 - return rv; 1663 - } 1664 - 1665 - /* 1666 - ** write cowfile from an absolute offset 1667 - ** 1668 - ** return-value: similar to user-mode write 1669 - */ 1670 - static long int 1671 - cowlo_writecowraw(struct cowloop_device *cowdev, 1672 - void *buf, int len, loff_t offset) 1673 - { 1674 - long int rv; 1675 - mm_segment_t old_fs; 1676 - loff_t saveoffset = offset; 1677 - 1678 - DEBUGP(DCOW"cowloop - writecowraw called\n"); 1679 - 1680 - /* 1681 - ** be sure that cowfile is opened for read-write 1682 - */ 1683 - if ( !(cowdev->state & COWRWCOWOPEN) ) { 1684 - printk(KERN_WARNING 1685 - "cowloop - write request to cowfile refused\n"); 1686 - 1687 - return -EBADF; 1688 - } 1689 - 1690 - /* 1691 - ** issue low level write 1692 - */ 1693 - old_fs = get_fs(); 1694 - set_fs( get_ds() ); 1695 - rv = cowdev->cowfp->f_op->write(cowdev->cowfp, buf, len, &offset); 1696 - set_fs(old_fs); 1697 - 1698 - if (rv < len) { 1699 - printk(KERN_WARNING 1700 - "cowloop - write-failure %ld on cowfile" 1701 - "- offset=%lld len=%d\n", rv, saveoffset, len); 1702 - } 1703 - 1704 - cowdev->cowwrites++; 1705 - return rv; 1706 - } 1707 - 1708 - 1709 - /* 1710 - ** readproc-function: called when the corresponding /proc-file is read 1711 - */ 1712 - static int 1713 - cowlo_readproc(char *buf, char **start, off_t pos, int cnt, int *eof, void *p) 1714 - { 1715 - struct cowloop_device *cowdev = p; 1716 - 1717 - revision[sizeof revision - 3] = '\0'; 1718 - 1719 - return sprintf(buf, 1720 - " cowloop version: %9s\n\n" 1721 - " device state: %s%s%s%s\n" 1722 - " number of opens: %9d\n" 1723 - " pid of thread: %9d\n\n" 1724 - " read-only file: %9s\n" 1725 - " rdoreads: %9lu\n\n" 1726 - "copy-on-write file: %9s\n" 1727 - " state cowfile: %9s\n" 1728 - " bitmap-blocks: %9lu (of %d bytes)\n" 1729 - " cowblocks in use: %9lu (of %d bytes)\n" 1730 - " cowreads: %9lu\n" 1731 - " cowwrites: %9lu\n", 1732 - &revision[11], 1733 - 1734 - cowdev->state & COWDEVOPEN ? "devopen " : "", 1735 - cowdev->state & COWRWCOWOPEN ? "cowopenrw " : "", 1736 - cowdev->state & COWRDCOWOPEN ? "cowopenro " : "", 1737 - cowdev->state & COWWATCHDOG ? "watchdog " : "", 1738 - 1739 - cowdev->opencnt, 1740 - cowdev->pid, 1741 - cowdev->rdoname, 1742 - cowdev->rdoreads, 1743 - cowdev->cowname, 1744 - cowdev->cowhead->flags & COWDIRTY ? "dirty":"clean", 1745 - cowdev->mapsize >> MUSHIFT, MAPUNIT, 1746 - cowdev->nrcowblocks, MAPUNIT, 1747 - cowdev->cowreads, 1748 - cowdev->cowwrites); 1749 - } 1750 - 1751 - /*****************************************************************************/ 1752 - /* Setup and destroy cowdevices */ 1753 - /*****************************************************************************/ 1754 - 1755 - /* 1756 - ** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps 1757 - ** 1758 - ** returns: 1759 - ** 0 - okay 1760 - ** < 0 - error value 1761 - */ 1762 - static int 1763 - cowlo_openpair(char *rdof, char *cowf, int autorecover, int minor) 1764 - { 1765 - long int rv; 1766 - struct cowloop_device *cowdev = cowdevall[minor]; 1767 - struct kstatfs ks; 1768 - 1769 - down(&cowdevlock); 1770 - 1771 - /* 1772 - ** requested device exists? 1773 - */ 1774 - if (minor >= maxcows) { 1775 - up(&cowdevlock); 1776 - return -ENODEV; 1777 - } 1778 - 1779 - /* 1780 - ** requested device already assigned to cowdevice? 1781 - */ 1782 - if (cowdev->state & COWDEVOPEN) { 1783 - up(&cowdevlock); 1784 - return -EBUSY; 1785 - } 1786 - 1787 - /* 1788 - ** initialize administration 1789 - */ 1790 - memset(cowdev, 0, sizeof *cowdev); 1791 - 1792 - spin_lock_init (&cowdev->rqlock); 1793 - init_waitqueue_head(&cowdev->waitq); 1794 - init_waitqueue_head(&cowdev->watchq); 1795 - 1796 - /* 1797 - ** open the read-only file 1798 - */ 1799 - DEBUGP(DCOW"cowloop - call openrdo....\n"); 1800 - 1801 - if ( (rv = cowlo_openrdo(cowdev, rdof)) ) { 1802 - cowlo_undo_openrdo(cowdev); 1803 - up(&cowdevlock); 1804 - return rv; 1805 - } 1806 - 1807 - /* 1808 - ** open the cowfile 1809 - */ 1810 - DEBUGP(DCOW"cowloop - call opencow....\n"); 1811 - 1812 - if ( (rv = cowlo_opencow(cowdev, cowf, autorecover)) ) { 1813 - cowlo_undo_openrdo(cowdev); 1814 - cowlo_undo_opencow(cowdev); 1815 - up(&cowdevlock); 1816 - return rv; 1817 - } 1818 - 1819 - /* 1820 - ** administer total and available size of filesystem holding cowfile 1821 - */ 1822 - if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0) { 1823 - cowdev->blksize = ks.f_bsize; 1824 - cowdev->blktotal = ks.f_blocks; 1825 - cowdev->blkavail = ks.f_bavail; 1826 - } else { 1827 - cowdev->blksize = 1024; /* avoid division by zero */ 1828 - } 1829 - 1830 - /* 1831 - ** flush the (recovered) bitmaps and cowhead to the cowfile 1832 - */ 1833 - DEBUGP(DCOW"cowloop - call cowsync....\n"); 1834 - 1835 - cowlo_sync(); 1836 - 1837 - /* 1838 - ** allocate gendisk for the cow device 1839 - */ 1840 - DEBUGP(DCOW"cowloop - alloc disk....\n"); 1841 - 1842 - if ((cowdev->gd = alloc_disk(1)) == NULL) { 1843 - printk(KERN_WARNING 1844 - "cowloop - unable to alloc_disk for cowloop\n"); 1845 - 1846 - cowlo_undo_openrdo(cowdev); 1847 - cowlo_undo_opencow(cowdev); 1848 - up(&cowdevlock); 1849 - return -ENOMEM; 1850 - } 1851 - 1852 - cowdev->gd->major = COWMAJOR; 1853 - cowdev->gd->first_minor = minor; 1854 - cowdev->gd->minors = 1; 1855 - cowdev->gd->fops = &cowlo_fops; 1856 - cowdev->gd->private_data = cowdev; 1857 - sprintf(cowdev->gd->disk_name, "%s%d", DEVICE_NAME, minor); 1858 - 1859 - /* in .5 Kb units */ 1860 - set_capacity(cowdev->gd, (cowdev->numblocks*(MAPUNIT/512))); 1861 - 1862 - DEBUGP(DCOW"cowloop - init request queue....\n"); 1863 - 1864 - if ((cowdev->rqueue = blk_init_queue(cowlo_request, &cowdev->rqlock)) 1865 - == NULL) { 1866 - printk(KERN_WARNING 1867 - "cowloop - unable to get request queue for cowloop\n"); 1868 - 1869 - del_gendisk(cowdev->gd); 1870 - cowlo_undo_openrdo(cowdev); 1871 - cowlo_undo_opencow(cowdev); 1872 - up(&cowdevlock); 1873 - return -EINVAL; 1874 - } 1875 - 1876 - blk_queue_logical_block_size(cowdev->rqueue, cowdev->blocksz); 1877 - cowdev->gd->queue = cowdev->rqueue; 1878 - 1879 - /* 1880 - ** start kernel thread to handle requests 1881 - */ 1882 - DEBUGP(DCOW"cowloop - kickoff daemon....\n"); 1883 - 1884 - cowdev->pid = kernel_thread((int (*)(void *))cowlo_daemon, cowdev, 0); 1885 - 1886 - /* 1887 - ** create a file below directory /proc/cow for this new cowdevice 1888 - */ 1889 - if (cowlo_procdir) { 1890 - char tmpname[64]; 1891 - 1892 - sprintf(tmpname, "%d", minor); 1893 - 1894 - create_proc_read_entry(tmpname, 0 , cowlo_procdir, 1895 - cowlo_readproc, cowdev); 1896 - } 1897 - 1898 - cowdev->state |= COWDEVOPEN; 1899 - 1900 - cowdev->rdoname = rdof; 1901 - cowdev->cowname = cowf; 1902 - 1903 - /* 1904 - ** enable the new disk; this triggers the first request! 1905 - */ 1906 - DEBUGP(DCOW"cowloop - call add_disk....\n"); 1907 - 1908 - add_disk(cowdev->gd); 1909 - 1910 - up(&cowdevlock); 1911 - return 0; 1912 - } 1913 - 1914 - /* 1915 - ** close a cowdevice (pair of rdofile/cowfile) and release memory 1916 - ** 1917 - ** returns: 1918 - ** 0 - okay 1919 - ** < 0 - error value 1920 - */ 1921 - static int 1922 - cowlo_closepair(struct cowloop_device *cowdev) 1923 - { 1924 - int minor; 1925 - 1926 - down(&cowdevlock); 1927 - 1928 - /* 1929 - ** if cowdevice is not activated at all, refuse 1930 - */ 1931 - if ( !(cowdev->state & COWDEVOPEN) ) { 1932 - up(&cowdevlock); 1933 - return -ENODEV; 1934 - } 1935 - 1936 - /* 1937 - ** if this cowdevice is still open, refuse 1938 - */ 1939 - if (cowdev->opencnt > 0) { 1940 - up(&cowdevlock); 1941 - return -EBUSY; 1942 - } 1943 - 1944 - up(&cowdevlock); 1945 - 1946 - /* 1947 - ** wakeup watcher (if any) 1948 - */ 1949 - if (cowdev->state & COWWATCHDOG) { 1950 - cowdev->watchthresh = cowdev->blkavail; 1951 - wake_up_interruptible(&cowdev->watchq); 1952 - } 1953 - 1954 - /* 1955 - ** wakeup kernel-thread to be able to exit 1956 - ** and wait until it has exited 1957 - */ 1958 - cowdev->closedown = 1; 1959 - cowdev->qfilled = 1; 1960 - wake_up_interruptible(&cowdev->waitq); 1961 - 1962 - while (cowdev->pid) 1963 - schedule(); 1964 - 1965 - del_gendisk(cowdev->gd); /* revert the alloc_disk() */ 1966 - put_disk(cowdev->gd); /* revert the add_disk() */ 1967 - 1968 - if (cowlo_procdir) { 1969 - char tmpname[64]; 1970 - 1971 - for (minor = 0; minor < maxcows; minor++) { 1972 - if (cowdev == cowdevall[minor]) break; 1973 - } 1974 - sprintf(tmpname, "%d", minor); 1975 - 1976 - remove_proc_entry(tmpname, cowlo_procdir); 1977 - } 1978 - 1979 - blk_cleanup_queue(cowdev->rqueue); 1980 - 1981 - /* 1982 - ** release memory for filenames if these names have 1983 - ** been allocated dynamically 1984 - */ 1985 - if ( (cowdev->cowname) && (cowdev->cowname != cowfile)) 1986 - kfree(cowdev->cowname); 1987 - 1988 - if ( (cowdev->rdoname) && (cowdev->rdoname != rdofile)) 1989 - kfree(cowdev->rdoname); 1990 - 1991 - cowlo_undo_openrdo(cowdev); 1992 - cowlo_undo_opencow(cowdev); 1993 - 1994 - cowdev->state &= ~COWDEVOPEN; 1995 - 1996 - return 0; 1997 - } 1998 - 1999 - /* 2000 - ** open the read-only file 2001 - ** 2002 - ** returns: 2003 - ** 0 - okay 2004 - ** < 0 - error value 2005 - */ 2006 - static int 2007 - cowlo_openrdo(struct cowloop_device *cowdev, char *rdof) 2008 - { 2009 - struct file *f; 2010 - struct inode *inode; 2011 - long int i, nrval; 2012 - 2013 - DEBUGP(DCOW"cowloop - openrdo called\n"); 2014 - 2015 - /* 2016 - ** open the read-only file 2017 - */ 2018 - if(*rdof == '\0') { 2019 - printk(KERN_ERR 2020 - "cowloop - specify name for read-only file\n\n"); 2021 - return -EINVAL; 2022 - } 2023 - 2024 - f = filp_open(rdof, O_RDONLY|O_LARGEFILE, 0); 2025 - 2026 - if ( (f == NULL) || IS_ERR(f) ) { 2027 - printk(KERN_ERR 2028 - "cowloop - open of rdofile %s failed\n", rdof); 2029 - return -EINVAL; 2030 - } 2031 - 2032 - cowdev->rdofp = f; 2033 - 2034 - inode = f->f_dentry->d_inode; 2035 - 2036 - if ( !S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode) ) { 2037 - printk(KERN_ERR 2038 - "cowloop - %s not regular file or blockdev\n", rdof); 2039 - return -EINVAL; 2040 - } 2041 - 2042 - DEBUGP(DCOW"cowloop - determine size rdo....\n"); 2043 - 2044 - /* 2045 - ** determine block-size and total size of read-only file 2046 - */ 2047 - if (S_ISREG(inode->i_mode)) { 2048 - /* 2049 - ** read-only file is a regular file 2050 - */ 2051 - cowdev->blocksz = 512; /* other value fails */ 2052 - cowdev->numblocks = inode->i_size >> MUSHIFT; 2053 - 2054 - if (inode->i_size & MUMASK) { 2055 - printk(KERN_WARNING 2056 - "cowloop - rdofile %s truncated to multiple " 2057 - "of %d bytes\n", rdof, MAPUNIT); 2058 - } 2059 - 2060 - DEBUGP(DCOW"cowloop - RO=regular: numblocks=%d, blocksz=%d\n", 2061 - cowdev->numblocks, cowdev->blocksz); 2062 - } else { 2063 - /* 2064 - ** read-only file is a block device 2065 - */ 2066 - cowdev->belowdev = inode->i_bdev; 2067 - cowdev->belowgd = cowdev->belowdev->bd_disk; /* gendisk */ 2068 - 2069 - if (cowdev->belowdev->bd_part) { 2070 - cowdev->numblocks = cowdev->belowdev->bd_part->nr_sects 2071 - / (MAPUNIT/512); 2072 - } 2073 - 2074 - if (cowdev->belowgd) { 2075 - cowdev->belowq = cowdev->belowgd->queue; 2076 - 2077 - if (cowdev->numblocks == 0) { 2078 - cowdev->numblocks = get_capacity(cowdev->belowgd) 2079 - / (MAPUNIT/512); 2080 - } 2081 - } 2082 - 2083 - 2084 - if (cowdev->belowq) 2085 - cowdev->blocksz = queue_logical_block_size(cowdev->belowq); 2086 - 2087 - if (cowdev->blocksz == 0) 2088 - cowdev->blocksz = BLOCK_SIZE; /* default 2^10 */ 2089 - 2090 - DEBUGP(DCOW"cowloop - numblocks=%d, " 2091 - "blocksz=%d, belowgd=%p, belowq=%p\n", 2092 - cowdev->numblocks, cowdev->blocksz, 2093 - cowdev->belowgd, cowdev->belowq); 2094 - 2095 - DEBUGP(DCOW"cowloop - belowdev.bd_block_size=%d\n", 2096 - cowdev->belowdev->bd_block_size); 2097 - } 2098 - 2099 - if (cowdev->numblocks == 0) { 2100 - printk(KERN_ERR "cowloop - %s has no contents\n", rdof); 2101 - return -EINVAL; 2102 - } 2103 - 2104 - /* 2105 - ** reserve space in memory as generic I/O buffer 2106 - */ 2107 - cowdev->iobuf = kmalloc(MAPUNIT, GFP_KERNEL); 2108 - 2109 - if (!cowdev->iobuf) { 2110 - printk(KERN_ERR 2111 - "cowloop - cannot get space for buffer %d\n", MAPUNIT); 2112 - return -ENOMEM; 2113 - } 2114 - 2115 - DEBUGP(DCOW"cowloop - determine fingerprint rdo....\n"); 2116 - 2117 - /* 2118 - ** determine fingerprint for read-only file 2119 - ** calculate fingerprint from first four datablocks 2120 - ** which do not contain binary zeroes 2121 - */ 2122 - for (i=0, cowdev->fingerprint=0, nrval=0; 2123 - (nrval < 4)&&(i < cowdev->numblocks); i++) { 2124 - int j; 2125 - unsigned char cs; 2126 - 2127 - /* 2128 - ** read next block 2129 - */ 2130 - if (cowlo_readrdo(cowdev, cowdev->iobuf, MAPUNIT, 2131 - (loff_t)i << MUSHIFT) < 1) 2132 - break; 2133 - 2134 - /* 2135 - ** calculate fingerprint by adding all byte-values 2136 - */ 2137 - for (j=0, cs=0; j < MAPUNIT; j++) 2138 - cs += *(cowdev->iobuf+j); 2139 - 2140 - if (cs == 0) /* block probably contained zeroes */ 2141 - continue; 2142 - 2143 - /* 2144 - ** shift byte-value to proper place in final fingerprint 2145 - */ 2146 - cowdev->fingerprint |= cs << (nrval*8); 2147 - nrval++; 2148 - } 2149 - 2150 - return 0; 2151 - } 2152 - 2153 - /* 2154 - ** undo memory allocs and file opens issued so far 2155 - ** related to the read-only file 2156 - */ 2157 - static void 2158 - cowlo_undo_openrdo(struct cowloop_device *cowdev) 2159 - { 2160 - if(cowdev->iobuf); 2161 - kfree(cowdev->iobuf); 2162 - 2163 - if (cowdev->rdofp) 2164 - filp_close(cowdev->rdofp, 0); 2165 - } 2166 - 2167 - /* 2168 - ** open the cowfile 2169 - ** 2170 - ** returns: 2171 - ** 0 - okay 2172 - ** < 0 - error value 2173 - */ 2174 - static int 2175 - cowlo_opencow(struct cowloop_device *cowdev, char *cowf, int autorecover) 2176 - { 2177 - long int i, rv; 2178 - int minor; 2179 - unsigned long nb; 2180 - struct file *f; 2181 - struct inode *inode; 2182 - loff_t offset; 2183 - struct cowloop_device *cowtmp; 2184 - 2185 - DEBUGP(DCOW"cowloop - opencow called\n"); 2186 - 2187 - /* 2188 - ** open copy-on-write file (read-write) 2189 - */ 2190 - if (cowf[0] == '\0') { 2191 - printk(KERN_ERR 2192 - "cowloop - specify name of copy-on-write file\n\n"); 2193 - return -EINVAL; 2194 - } 2195 - 2196 - f = filp_open(cowf, O_RDWR|O_LARGEFILE, 0600); 2197 - 2198 - if ( (f == NULL) || IS_ERR(f) ) { 2199 - /* 2200 - ** non-existing cowfile: try to create 2201 - */ 2202 - f = filp_open(cowf, O_RDWR|O_CREAT|O_LARGEFILE, 0600); 2203 - 2204 - if ( (f == NULL) || IS_ERR(f) ) { 2205 - printk(KERN_ERR 2206 - "cowloop - failed to open file %s for read-write\n\n", 2207 - cowf); 2208 - return -EINVAL; 2209 - } 2210 - } 2211 - 2212 - cowdev->cowfp = f; 2213 - 2214 - inode = f->f_dentry->d_inode; 2215 - 2216 - if (!S_ISREG(inode->i_mode)) { 2217 - printk(KERN_ERR "cowloop - %s is not regular file\n", cowf); 2218 - return -EINVAL; 2219 - } 2220 - 2221 - /* 2222 - ** check if this cowfile is already in use for another cowdevice 2223 - */ 2224 - for (minor = 0; minor < maxcows; minor++) { 2225 - 2226 - cowtmp = cowdevall[minor]; 2227 - 2228 - if ( !(cowtmp->state & COWDEVOPEN) ) 2229 - continue; 2230 - 2231 - if (cowtmp == cowdev) 2232 - continue; 2233 - 2234 - if (cowtmp->cowfp->f_dentry->d_inode == f->f_dentry->d_inode) { 2235 - printk(KERN_ERR 2236 - "cowloop - %s: already in use as cow\n", cowf); 2237 - return -EBUSY; 2238 - } 2239 - } 2240 - 2241 - /* 2242 - ** mark cowfile open for read-write 2243 - */ 2244 - cowdev->state |= COWRWCOWOPEN; 2245 - 2246 - /* 2247 - ** calculate size (in bytes) for total bitmap in cowfile; 2248 - ** when the size of the cowhead block is added, the start-offset 2249 - ** for the modified data blocks can be found 2250 - */ 2251 - nb = cowdev->numblocks; 2252 - 2253 - if (nb%8) /* transform #bits to #bytes */ 2254 - nb+=8; /* rounded if necessary */ 2255 - nb /= 8; 2256 - 2257 - if (nb & MUMASK) /* round up #bytes to MAPUNIT chunks */ 2258 - cowdev->mapsize = ( (nb>>MUSHIFT) +1) << MUSHIFT; 2259 - else 2260 - cowdev->mapsize = nb; 2261 - 2262 - /* 2263 - ** reserve space in memory for the cowhead 2264 - */ 2265 - cowdev->cowhead = kmalloc(MAPUNIT, GFP_KERNEL); 2266 - 2267 - if (!cowdev->cowhead) { 2268 - printk(KERN_ERR "cowloop - cannot get space for cowhead %d\n", 2269 - MAPUNIT); 2270 - return -ENOMEM; 2271 - } 2272 - 2273 - memset(cowdev->cowhead, 0, MAPUNIT); 2274 - 2275 - DEBUGP(DCOW"cowloop - prepare cowhead....\n"); 2276 - 2277 - /* 2278 - ** check if the cowfile exists or should be created 2279 - */ 2280 - if (inode->i_size != 0) { 2281 - /* 2282 - ** existing cowfile: read the cow head 2283 - */ 2284 - if (inode->i_size < MAPUNIT) { 2285 - printk(KERN_ERR 2286 - "cowloop - existing cowfile %s too small\n", 2287 - cowf); 2288 - return -EINVAL; 2289 - } 2290 - 2291 - cowlo_readcowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0); 2292 - 2293 - /* 2294 - ** verify if the existing file is really a cowfile 2295 - */ 2296 - if (cowdev->cowhead->magic != COWMAGIC) { 2297 - printk(KERN_ERR 2298 - "cowloop - cowfile %s has incorrect format\n", 2299 - cowf); 2300 - return -EINVAL; 2301 - } 2302 - 2303 - /* 2304 - ** verify the cowhead version of the cowfile 2305 - */ 2306 - if (cowdev->cowhead->version > COWVERSION) { 2307 - printk(KERN_ERR 2308 - "cowloop - cowfile %s newer than this driver\n", 2309 - cowf); 2310 - return -EINVAL; 2311 - } 2312 - 2313 - /* 2314 - ** make sure that this is not a packed cowfile 2315 - */ 2316 - if (cowdev->cowhead->flags & COWPACKED) { 2317 - printk(KERN_ERR 2318 - "cowloop - packed cowfile %s not accepted\n", cowf); 2319 - return -EINVAL; 2320 - } 2321 - 2322 - /* 2323 - ** verify if the cowfile has been properly closed 2324 - */ 2325 - if (cowdev->cowhead->flags & COWDIRTY) { 2326 - /* 2327 - ** cowfile was not properly closed; 2328 - ** check if automatic recovery is required 2329 - ** (actual recovery will be done later on) 2330 - */ 2331 - if (!autorecover) { 2332 - printk(KERN_ERR 2333 - "cowloop - cowfile %s is dirty " 2334 - "(not properly closed by rmmod?)\n", 2335 - cowf); 2336 - printk(KERN_ERR 2337 - "cowloop - run cowrepair or specify " 2338 - "'option=r' to recover\n"); 2339 - return -EINVAL; 2340 - } 2341 - } 2342 - 2343 - /* 2344 - ** verify if the cowfile is really related to this rdofile 2345 - */ 2346 - if (cowdev->cowhead->rdoblocks != cowdev->numblocks) { 2347 - printk(KERN_ERR 2348 - "cowloop - cowfile %s (size %lld) not related " 2349 - "to rdofile (size %lld)\n", 2350 - cowf, 2351 - (long long)cowdev->cowhead->rdoblocks <<MUSHIFT, 2352 - (long long)cowdev->numblocks <<MUSHIFT); 2353 - return -EINVAL; 2354 - } 2355 - 2356 - if (cowdev->cowhead->rdofingerprint != cowdev->fingerprint) { 2357 - printk(KERN_ERR 2358 - "cowloop - cowfile %s not related to rdofile " 2359 - " (fingerprint err - rdofile modified?)\n", cowf); 2360 - return -EINVAL; 2361 - } 2362 - } else { 2363 - /* 2364 - ** new cowfile: determine the minimal size (cowhead+bitmap) 2365 - */ 2366 - offset = (loff_t) MAPUNIT + cowdev->mapsize - 1; 2367 - 2368 - if ( cowlo_writecowraw(cowdev, "", 1, offset) < 1) { 2369 - printk(KERN_ERR 2370 - "cowloop - cannot set cowfile to size %lld\n", 2371 - offset+1); 2372 - return -EINVAL; 2373 - } 2374 - 2375 - /* 2376 - ** prepare new cowhead 2377 - */ 2378 - cowdev->cowhead->magic = COWMAGIC; 2379 - cowdev->cowhead->version = COWVERSION; 2380 - cowdev->cowhead->mapunit = MAPUNIT; 2381 - cowdev->cowhead->mapsize = cowdev->mapsize; 2382 - cowdev->cowhead->rdoblocks = cowdev->numblocks; 2383 - cowdev->cowhead->rdofingerprint = cowdev->fingerprint; 2384 - cowdev->cowhead->cowused = 0; 2385 - 2386 - /* 2387 - ** calculate start offset of data in cowfile, 2388 - ** rounded up to multiple of 4K to avoid 2389 - ** unnecessary disk-usage for written datablocks in 2390 - ** the sparsed cowfile on e.g. 4K filesystems 2391 - */ 2392 - cowdev->cowhead->doffset = 2393 - ((MAPUNIT+cowdev->mapsize+4095)>>12)<<12; 2394 - } 2395 - 2396 - cowdev->cowhead->flags = 0; 2397 - 2398 - DEBUGP(DCOW"cowloop - reserve space bitmap....\n"); 2399 - 2400 - /* 2401 - ** reserve space in memory for the entire bitmap and 2402 - ** fill it with the bitmap-data from disk; the entire 2403 - ** bitmap is allocated in several chunks because kmalloc 2404 - ** has restrictions regarding the allowed size per kmalloc 2405 - */ 2406 - cowdev->mapcount = (cowdev->mapsize+MAPCHUNKSZ-1)/MAPCHUNKSZ; 2407 - 2408 - /* 2409 - ** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for 2410 - ** the last bitmap chunk: calculate remaining size for this chunk 2411 - */ 2412 - if (cowdev->mapsize % MAPCHUNKSZ == 0) 2413 - cowdev->mapremain = MAPCHUNKSZ; 2414 - else 2415 - cowdev->mapremain = cowdev->mapsize % MAPCHUNKSZ; 2416 - 2417 - /* 2418 - ** allocate space to store all pointers for the bitmap-chunks 2419 - ** (initialize area with zeroes to allow proper undo) 2420 - */ 2421 - cowdev->mapcache = kmalloc(cowdev->mapcount * sizeof(char *), 2422 - GFP_KERNEL); 2423 - if (!cowdev->mapcache) { 2424 - printk(KERN_ERR 2425 - "cowloop - can not allocate space for bitmap ptrs\n"); 2426 - return -ENOMEM; 2427 - } 2428 - 2429 - memset(cowdev->mapcache, 0, cowdev->mapcount * sizeof(char *)); 2430 - 2431 - /* 2432 - ** allocate space to store the bitmap-chunks themselves 2433 - */ 2434 - for (i=0; i < cowdev->mapcount; i++) { 2435 - if (i < (cowdev->mapcount-1)) 2436 - *(cowdev->mapcache+i) = kmalloc(MAPCHUNKSZ, GFP_KERNEL); 2437 - else 2438 - *(cowdev->mapcache+i) = kmalloc(cowdev->mapremain, 2439 - GFP_KERNEL); 2440 - 2441 - if (*(cowdev->mapcache+i) == NULL) { 2442 - printk(KERN_ERR "cowloop - no space for bitmapchunk %ld" 2443 - " totmapsz=%ld, mapcnt=%d mapunit=%d\n", 2444 - i, cowdev->mapsize, cowdev->mapcount, 2445 - MAPUNIT); 2446 - return -ENOMEM; 2447 - } 2448 - } 2449 - 2450 - DEBUGP(DCOW"cowloop - read bitmap from cow....\n"); 2451 - 2452 - /* 2453 - ** read the entire bitmap from the cowfile into the in-memory cache; 2454 - ** count the number of blocks that are in use already 2455 - ** (statistical purposes) 2456 - */ 2457 - for (i=0, offset=MAPUNIT; i < cowdev->mapcount; 2458 - i++, offset+=MAPCHUNKSZ) { 2459 - unsigned long numbytes; 2460 - 2461 - if (i < (cowdev->mapcount-1)) 2462 - /* 2463 - ** full bitmap chunk 2464 - */ 2465 - numbytes = MAPCHUNKSZ; 2466 - else 2467 - /* 2468 - ** last bitmap chunk: might be partly filled 2469 - */ 2470 - numbytes = cowdev->mapremain; 2471 - 2472 - cowlo_readcowraw(cowdev, *(cowdev->mapcache+i), 2473 - numbytes, offset); 2474 - } 2475 - 2476 - /* 2477 - ** if the cowfile was dirty and automatic recovery is required, 2478 - ** reconstruct a proper bitmap in memory now 2479 - */ 2480 - if (cowdev->cowhead->flags & COWDIRTY) { 2481 - unsigned long long blocknum; 2482 - char databuf[MAPUNIT]; 2483 - unsigned long mapnum, mapbyte, mapbit; 2484 - 2485 - printk(KERN_NOTICE "cowloop - recover dirty cowfile %s....\n", 2486 - cowf); 2487 - 2488 - /* 2489 - ** read all data blocks 2490 - */ 2491 - for (blocknum=0, rv=1, offset=0; 2492 - cowlo_readcow(cowdev, databuf, MAPUNIT, offset) > 0; 2493 - blocknum++, offset += MAPUNIT) { 2494 - 2495 - /* 2496 - ** if this datablock contains real data (not binary 2497 - ** zeroes), set the corresponding bit in the bitmap 2498 - */ 2499 - if ( memcmp(databuf, allzeroes, MAPUNIT) == 0) 2500 - continue; 2501 - 2502 - mapnum = CALCMAP (blocknum); 2503 - mapbyte = CALCBYTE(blocknum); 2504 - mapbit = CALCBIT (blocknum); 2505 - 2506 - *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit); 2507 - } 2508 - 2509 - printk(KERN_NOTICE "cowloop - cowfile recovery completed\n"); 2510 - } 2511 - 2512 - /* 2513 - ** count all bits set in the bitmaps for statistical purposes 2514 - */ 2515 - for (i=0, cowdev->nrcowblocks = 0; i < cowdev->mapcount; i++) { 2516 - long numbytes; 2517 - char *p; 2518 - 2519 - if (i < (cowdev->mapcount-1)) 2520 - numbytes = MAPCHUNKSZ; 2521 - else 2522 - numbytes = cowdev->mapremain; 2523 - 2524 - p = *(cowdev->mapcache+i); 2525 - 2526 - for (numbytes--; numbytes >= 0; numbytes--, p++) { 2527 - /* 2528 - ** for only eight checks the following construction 2529 - ** is faster than a loop-construction 2530 - */ 2531 - if ((*p) & 0x01) cowdev->nrcowblocks++; 2532 - if ((*p) & 0x02) cowdev->nrcowblocks++; 2533 - if ((*p) & 0x04) cowdev->nrcowblocks++; 2534 - if ((*p) & 0x08) cowdev->nrcowblocks++; 2535 - if ((*p) & 0x10) cowdev->nrcowblocks++; 2536 - if ((*p) & 0x20) cowdev->nrcowblocks++; 2537 - if ((*p) & 0x40) cowdev->nrcowblocks++; 2538 - if ((*p) & 0x80) cowdev->nrcowblocks++; 2539 - } 2540 - } 2541 - 2542 - /* 2543 - ** consistency-check for number of bits set in bitmap 2544 - */ 2545 - if ( !(cowdev->cowhead->flags & COWDIRTY) && 2546 - (cowdev->cowhead->cowused != cowdev->nrcowblocks) ) { 2547 - printk(KERN_ERR "cowloop - inconsistent cowfile admi\n"); 2548 - return -EINVAL; 2549 - } 2550 - 2551 - return 0; 2552 - } 2553 - 2554 - /* 2555 - ** undo memory allocs and file opens issued so far 2556 - ** related to the cowfile 2557 - */ 2558 - static void 2559 - cowlo_undo_opencow(struct cowloop_device *cowdev) 2560 - { 2561 - int i; 2562 - 2563 - if (cowdev->mapcache) { 2564 - for (i=0; i < cowdev->mapcount; i++) { 2565 - if (*(cowdev->mapcache+i) != NULL) 2566 - kfree( *(cowdev->mapcache+i) ); 2567 - } 2568 - 2569 - kfree(cowdev->mapcache); 2570 - } 2571 - 2572 - if (cowdev->cowhead) 2573 - kfree(cowdev->cowhead); 2574 - 2575 - if ( (cowdev->state & COWCOWOPEN) && (cowdev->cowfp) ) 2576 - filp_close(cowdev->cowfp, 0); 2577 - 2578 - /* 2579 - ** mark cowfile closed 2580 - */ 2581 - cowdev->state &= ~COWCOWOPEN; 2582 - } 2583 - 2584 - /* 2585 - ** flush the entire bitmap and the cowhead (clean) to the cowfile 2586 - ** 2587 - ** must be called with the cowdevices-lock set 2588 - */ 2589 - static void 2590 - cowlo_sync(void) 2591 - { 2592 - int i, minor; 2593 - loff_t offset; 2594 - struct cowloop_device *cowdev; 2595 - 2596 - for (minor=0; minor < maxcows; minor++) { 2597 - cowdev = cowdevall[minor]; 2598 - if ( ! (cowdev->state & COWRWCOWOPEN) ) 2599 - continue; 2600 - 2601 - for (i=0, offset=MAPUNIT; i < cowdev->mapcount; 2602 - i++, offset += MAPCHUNKSZ) { 2603 - unsigned long numbytes; 2604 - 2605 - if (i < (cowdev->mapcount-1)) 2606 - /* 2607 - ** full bitmap chunk 2608 - */ 2609 - numbytes = MAPCHUNKSZ; 2610 - else 2611 - /* 2612 - ** last bitmap chunk: might be partly filled 2613 - */ 2614 - numbytes = cowdev->mapremain; 2615 - 2616 - DEBUGP(DCOW 2617 - "cowloop - flushing bitmap %2d (%3ld Kb)\n", 2618 - i, numbytes/1024); 2619 - 2620 - if (cowlo_writecowraw(cowdev, *(cowdev->mapcache+i), 2621 - numbytes, offset) < numbytes) { 2622 - break; 2623 - } 2624 - } 2625 - 2626 - /* 2627 - ** flush clean up-to-date cowhead to cowfile 2628 - */ 2629 - cowdev->cowhead->cowused = cowdev->nrcowblocks; 2630 - cowdev->cowhead->flags &= ~COWDIRTY; 2631 - 2632 - DEBUGP(DCOW "cowloop - flushing cowhead (%3d Kb)\n", 2633 - MAPUNIT/1024); 2634 - 2635 - cowlo_writecowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0); 2636 - } 2637 - } 2638 - 2639 - /*****************************************************************************/ 2640 - /* Module loading/unloading */ 2641 - /*****************************************************************************/ 2642 - 2643 - /* 2644 - ** called during insmod/modprobe 2645 - */ 2646 - static int __init 2647 - cowlo_init_module(void) 2648 - { 2649 - int rv; 2650 - int minor, uptocows; 2651 - 2652 - revision[sizeof revision - 3] = '\0'; 2653 - 2654 - printk(KERN_NOTICE "cowloop - (C) 2009 ATComputing.nl - version: %s\n", &revision[11]); 2655 - printk(KERN_NOTICE "cowloop - info: www.ATComputing.nl/cowloop\n"); 2656 - 2657 - memset(allzeroes, 0, MAPUNIT); 2658 - 2659 - /* 2660 - ** Setup administration for all possible cowdevices. 2661 - ** Note that their minor numbers go from 0 to MAXCOWS-1 inclusive 2662 - ** and minor == MAXCOWS-1 is reserved for the control device. 2663 - */ 2664 - if ((maxcows < 1) || (maxcows > MAXCOWS)) { 2665 - printk(KERN_WARNING 2666 - "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS); 2667 - 2668 - maxcows = DFLCOWS; 2669 - } 2670 - 2671 - /* allocate room for a table with a pointer to each cowloop_device: */ 2672 - if ( (cowdevall = kmalloc(maxcows * sizeof(struct cowloop_device *), 2673 - GFP_KERNEL)) == NULL) { 2674 - printk(KERN_WARNING 2675 - "cowloop - can not alloc table for %d devs\n", maxcows); 2676 - uptocows = 0; 2677 - rv = -ENOMEM; 2678 - goto error_out; 2679 - } 2680 - memset(cowdevall, 0, maxcows * sizeof(struct cowloop_device *)); 2681 - /* then hook an actual cowloop_device struct to each pointer: */ 2682 - for (minor=0; minor < maxcows; minor++) { 2683 - if ((cowdevall[minor] = kmalloc(sizeof(struct cowloop_device), 2684 - GFP_KERNEL)) == NULL) { 2685 - printk(KERN_WARNING 2686 - "cowloop - can not alloc admin-struct for dev no %d\n", minor); 2687 - 2688 - uptocows = minor; /* this is how far we got.... */ 2689 - rv = -ENOMEM; 2690 - goto error_out; 2691 - } 2692 - memset(cowdevall[minor], 0, sizeof(struct cowloop_device)); 2693 - } 2694 - uptocows = maxcows; /* we got all devices */ 2695 - 2696 - sema_init(&cowdevlock, 1); 2697 - 2698 - /* 2699 - ** register cowloop module 2700 - */ 2701 - if ( register_blkdev(COWMAJOR, DEVICE_NAME) < 0) { 2702 - printk(KERN_WARNING 2703 - "cowloop - unable to get major %d for cowloop\n", COWMAJOR); 2704 - rv = -EIO; 2705 - goto error_out; 2706 - } 2707 - 2708 - /* 2709 - ** create a directory below /proc to allocate a file 2710 - ** for each cowdevice that is allocated later on 2711 - */ 2712 - cowlo_procdir = proc_mkdir("cow", NULL); 2713 - 2714 - /* 2715 - ** check if a cowdevice has to be opened during insmod/modprobe; 2716 - ** two parameters should be specified then: rdofile= and cowfile= 2717 - */ 2718 - if( (rdofile[0] != '\0') && (cowfile[0] != '\0') ) { 2719 - char *po = option; 2720 - int wantrecover = 0; 2721 - 2722 - /* 2723 - ** check if automatic recovery is wanted 2724 - */ 2725 - while (*po) { 2726 - if (*po == 'r') { 2727 - wantrecover = 1; 2728 - break; 2729 - } 2730 - po++; 2731 - } 2732 - 2733 - /* 2734 - ** open new cowdevice with minor number 0 2735 - */ 2736 - if ( (rv = cowlo_openpair(rdofile, cowfile, wantrecover, 0))) { 2737 - remove_proc_entry("cow", NULL); 2738 - unregister_blkdev(COWMAJOR, DEVICE_NAME); 2739 - goto error_out; 2740 - } 2741 - } else { 2742 - /* 2743 - ** check if only one parameter has been specified 2744 - */ 2745 - if( (rdofile[0] != '\0') || (cowfile[0] != '\0') ) { 2746 - printk(KERN_ERR 2747 - "cowloop - only one filename specified\n"); 2748 - remove_proc_entry("cow", NULL); 2749 - unregister_blkdev(COWMAJOR, DEVICE_NAME); 2750 - rv = -EINVAL; 2751 - goto error_out; 2752 - } 2753 - } 2754 - 2755 - /* 2756 - ** allocate fake disk as control channel to handle the requests 2757 - ** to activate and deactivate cowdevices dynamically 2758 - */ 2759 - if (!(cowctlgd = alloc_disk(1))) { 2760 - printk(KERN_WARNING 2761 - "cowloop - unable to alloc_disk for cowctl\n"); 2762 - 2763 - remove_proc_entry("cow", NULL); 2764 - (void) cowlo_closepair(cowdevall[0]); 2765 - unregister_blkdev(COWMAJOR, DEVICE_NAME); 2766 - rv = -ENOMEM; 2767 - goto error_out; 2768 - } 2769 - 2770 - spin_lock_init(&cowctlrqlock); 2771 - cowctlgd->major = COWMAJOR; 2772 - cowctlgd->first_minor = COWCTL; 2773 - cowctlgd->minors = 1; 2774 - cowctlgd->fops = &cowlo_fops; 2775 - cowctlgd->private_data = NULL; 2776 - /* the device has capacity 0, so there will be no q-requests */ 2777 - cowctlgd->queue = blk_init_queue(NULL, &cowctlrqlock); 2778 - sprintf(cowctlgd->disk_name, "cowctl"); 2779 - set_capacity(cowctlgd, 0); 2780 - 2781 - add_disk(cowctlgd); 2782 - 2783 - printk(KERN_NOTICE "cowloop - number of configured cowdevices: %d\n", 2784 - maxcows); 2785 - if (rdofile[0] != '\0') { 2786 - printk(KERN_NOTICE "cowloop - initialized on rdofile=%s\n", 2787 - rdofile); 2788 - } else { 2789 - printk(KERN_NOTICE "cowloop - initialized without rdofile yet\n"); 2790 - } 2791 - return 0; 2792 - 2793 - error_out: 2794 - for (minor=0; minor < uptocows ; minor++) { 2795 - kfree(cowdevall[minor]); 2796 - } 2797 - kfree(cowdevall); 2798 - return rv; 2799 - } 2800 - 2801 - /* 2802 - ** called during rmmod 2803 - */ 2804 - static void __exit 2805 - cowlo_cleanup_module(void) 2806 - { 2807 - int minor; 2808 - 2809 - /* 2810 - ** flush bitmaps and cowheads to the cowfiles 2811 - */ 2812 - down(&cowdevlock); 2813 - cowlo_sync(); 2814 - up(&cowdevlock); 2815 - 2816 - /* 2817 - ** close all cowdevices 2818 - */ 2819 - for (minor=0; minor < maxcows; minor++) 2820 - (void) cowlo_closepair(cowdevall[minor]); 2821 - 2822 - unregister_blkdev(COWMAJOR, DEVICE_NAME); 2823 - 2824 - /* 2825 - ** get rid of /proc/cow and unregister the driver 2826 - */ 2827 - remove_proc_entry("cow", NULL); 2828 - 2829 - for (minor = 0; minor < maxcows; minor++) { 2830 - kfree(cowdevall[minor]); 2831 - } 2832 - kfree(cowdevall); 2833 - 2834 - del_gendisk(cowctlgd); /* revert the alloc_disk() */ 2835 - put_disk (cowctlgd); /* revert the add_disk() */ 2836 - blk_cleanup_queue(cowctlgd->queue); /* cleanup the empty queue */ 2837 - 2838 - printk(KERN_NOTICE "cowloop - unloaded\n"); 2839 - } 2840 - 2841 - module_init(cowlo_init_module); 2842 - module_exit(cowlo_cleanup_module);
-66
drivers/staging/cowloop/cowloop.h
··· 1 - /* 2 - ** DO NOT MODIFY THESE VALUES (would make old cowfiles unusable) 3 - */ 4 - #define MAPUNIT 1024 /* blocksize for bit in bitmap */ 5 - #define MUSHIFT 10 /* bitshift for bit in bitmap */ 6 - #define MUMASK 0x3ff /* bitmask for bit in bitmap */ 7 - 8 - #define COWMAGIC 0x574f437f /* byte-swapped '7f C O W' */ 9 - #define COWDIRTY 0x01 10 - #define COWPACKED 0x02 11 - #define COWVERSION 1 12 - 13 - struct cowhead 14 - { 15 - int magic; /* identifies a cowfile */ 16 - short version; /* version of cowhead */ 17 - short flags; /* flags indicating status */ 18 - unsigned long mapunit; /* blocksize per bit in bitmap */ 19 - unsigned long mapsize; /* total size of bitmap (bytes) */ 20 - unsigned long doffset; /* start-offset datablocks in cow */ 21 - unsigned long rdoblocks; /* size of related read-only file */ 22 - unsigned long rdofingerprint; /* fingerprint of read-only file */ 23 - unsigned long cowused; /* number of datablocks used in cow */ 24 - }; 25 - 26 - #define COWDEVDIR "/dev/cow/" 27 - #define COWDEVICE COWDEVDIR "%ld" 28 - #define COWCONTROL COWDEVDIR "ctl" 29 - 30 - #define MAXCOWS 1024 31 - #define COWCTL (MAXCOWS-1) /* minor number of /dev/cow/ctl */ 32 - 33 - #define COWPROCDIR "/proc/cow/" 34 - #define COWPROCFILE COWPROCDIR "%d" 35 - 36 - /* 37 - ** ioctl related stuff 38 - */ 39 - #define ANYDEV ((unsigned long)-1) 40 - 41 - struct cowpair 42 - { 43 - unsigned char *rdofile; /* pathname of the rdofile */ 44 - unsigned char *cowfile; /* pathname of the cowfile */ 45 - unsigned short rdoflen; /* length of rdofile pathname */ 46 - unsigned short cowflen; /* length of cowfile pathname */ 47 - unsigned long device; /* requested/returned device number */ 48 - }; 49 - 50 - struct cowwatch 51 - { 52 - int flags; /* request flags */ 53 - unsigned long device; /* requested device number */ 54 - unsigned long threshold; /* continue if free Kb < threshold */ 55 - unsigned long totalkb; /* ret: total filesystem size (Kb) */ 56 - unsigned long availkb; /* ret: free filesystem size (Kb) */ 57 - }; 58 - 59 - #define WATCHWAIT 0x01 /* block until threshold reached */ 60 - 61 - #define COWSYNC _IO ('C', 1) 62 - #define COWMKPAIR _IOW ('C', 2, struct cowpair) 63 - #define COWRMPAIR _IOW ('C', 3, unsigned long) 64 - #define COWWATCH _IOW ('C', 4, struct cowwatch) 65 - #define COWCLOSE _IOW ('C', 5, unsigned long) 66 - #define COWRDOPEN _IOW ('C', 6, unsigned long)
+1
drivers/staging/iio/Kconfig
··· 4 4 5 5 menuconfig IIO 6 6 tristate "Industrial I/O support" 7 + depends on !S390 7 8 ---help--- 8 9 The industrial I/O subsystem provides a unified framework for 9 10 drivers for many different types of embedded sensors using a
+8 -6
drivers/staging/p9auth/p9auth.c
··· 183 183 user_buf_running = NULL; 184 184 hash_str = NULL; 185 185 node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL); 186 - user_buf = kzalloc(count, GFP_KERNEL); 186 + user_buf = kzalloc(count+1, GFP_KERNEL); 187 187 if (!node_ptr || !user_buf) 188 188 goto out; 189 189 ··· 207 207 list_add(&(node_ptr->list), &(dev->head->list)); 208 208 node_ptr = NULL; 209 209 } else { 210 + char *tmpu; 210 211 if (!cap_devices[0].head || 211 212 list_empty(&(cap_devices[0].head->list))) { 212 213 retval = -EINVAL; ··· 219 218 * need to split it and hash 'user1@user2' using 'randomstring' 220 219 * as the key. 221 220 */ 222 - user_buf_running = kstrdup(user_buf, GFP_KERNEL); 223 - source_user = strsep(&user_buf_running, "@"); 224 - target_user = strsep(&user_buf_running, "@"); 225 - rand_str = strsep(&user_buf_running, "@"); 221 + tmpu = user_buf_running = kstrdup(user_buf, GFP_KERNEL); 222 + source_user = strsep(&tmpu, "@"); 223 + target_user = strsep(&tmpu, "@"); 224 + rand_str = tmpu; 226 225 if (!source_user || !target_user || !rand_str) { 227 226 retval = -EINVAL; 228 227 goto out; ··· 230 229 231 230 /* hash the string user1@user2 with rand_str as the key */ 232 231 len = strlen(source_user) + strlen(target_user) + 1; 233 - hash_str = kzalloc(len, GFP_KERNEL); 232 + /* src, @, len, \0 */ 233 + hash_str = kzalloc(len+1, GFP_KERNEL); 234 234 strcat(hash_str, source_user); 235 235 strcat(hash_str, "@"); 236 236 strcat(hash_str, target_user);
+1
drivers/staging/rtl8192e/r8192E_core.c
··· 46 46 #undef DEBUG_TX_DESC 47 47 48 48 //#define CONFIG_RTL8192_IO_MAP 49 + #include <linux/vmalloc.h> 49 50 #include <asm/uaccess.h> 50 51 #include "r8192E_hw.h" 51 52 #include "r8192E.h"
+26 -18
drivers/staging/winbond/wbusb.c
··· 51 51 .n_bitrates = ARRAY_SIZE(wbsoft_rates), 52 52 }; 53 53 54 + static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) 55 + { 56 + u32 tmp; 57 + 58 + if (pHwData->SurpriseRemove) 59 + return; 60 + 61 + pHwData->BeaconPeriod = beacon_period; 62 + tmp = pHwData->BeaconPeriod << 16; 63 + tmp |= pHwData->ProbeDelay; 64 + Wb35Reg_Write(pHwData, 0x0848, tmp); 65 + } 66 + 54 67 static int wbsoft_add_interface(struct ieee80211_hw *dev, 55 68 struct ieee80211_if_init_conf *conf) 56 69 { 57 - printk("wbsoft_add interface called\n"); 70 + struct wbsoft_priv *priv = dev->priv; 71 + 72 + hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int); 73 + 58 74 return 0; 59 75 } 60 76 ··· 99 83 return 0; 100 84 } 101 85 86 + static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count, 87 + struct dev_addr_list *mc_list) 88 + { 89 + return mc_count; 90 + } 91 + 102 92 static void wbsoft_configure_filter(struct ieee80211_hw *dev, 103 93 unsigned int changed_flags, 104 94 unsigned int *total_flags, 105 - int mc_count, struct dev_mc_list *mclist) 95 + u64 multicast) 106 96 { 107 97 unsigned int new_flags; 108 98 ··· 116 94 117 95 if (*total_flags & FIF_PROMISC_IN_BSS) 118 96 new_flags |= FIF_PROMISC_IN_BSS; 119 - else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) 97 + else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32)) 120 98 new_flags |= FIF_ALLMULTI; 121 99 122 100 dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; ··· 158 136 reg->M24_MacControl |= 0x00000040; 159 137 } 160 138 Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl); 161 - } 162 - 163 - static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period) 164 - { 165 - u32 tmp; 166 - 167 - if (pHwData->SurpriseRemove) 168 - return; 169 - 170 - pHwData->BeaconPeriod = beacon_period; 171 - tmp = pHwData->BeaconPeriod << 16; 172 - tmp |= pHwData->ProbeDelay; 173 - Wb35Reg_Write(pHwData, 0x0848, tmp); 174 139 } 175 140 176 141 static void ··· 253 244 static int wbsoft_config(struct ieee80211_hw *dev, u32 changed) 254 245 { 255 246 struct wbsoft_priv *priv = dev->priv; 256 - struct ieee80211_conf *conf = &dev->conf; 257 247 ChanInfo ch; 258 248 259 249 printk("wbsoft_config called\n"); ··· 262 254 ch.ChanNo = 1; 263 255 264 256 hal_set_current_channel(&priv->sHwData, ch); 265 - hal_set_beacon_period(&priv->sHwData, conf->beacon_int); 266 257 hal_set_accept_broadcast(&priv->sHwData, 1); 267 258 hal_set_accept_promiscuous(&priv->sHwData, 1); 268 259 hal_set_accept_multicast(&priv->sHwData, 1); ··· 284 277 .add_interface = wbsoft_add_interface, 285 278 .remove_interface = wbsoft_remove_interface, 286 279 .config = wbsoft_config, 280 + .prepare_multicast = wbsoft_prepare_multicast, 287 281 .configure_filter = wbsoft_configure_filter, 288 282 .get_stats = wbsoft_get_stats, 289 283 .get_tx_stats = wbsoft_get_tx_stats,