aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_chip.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-12-11 20:26:11 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-05 16:58:42 -0500
commit0ce34bc8f7d906d66ce6803f63399ef9bbe54012 (patch)
tree1326f9105842fc81f89bf8ab1a435ab13a4d72d5 /drivers/net/wireless/zd1211rw/zd_chip.c
parentee30276774451d657407855d95d9393ee8bc0bac (diff)
[PATCH] zd1211rw: Remove addressing abstraction
Instead of passing our own custom 32-bit addresses around and translating them, this patch makes all our register address constants absolute and removes the translation. There are two ugly parts: - fw_reg_addr() is needed to compute addresses of firmware registers, as this is dynamic based upon firmware - inc_addr() needs a small hack to handle byte vs word addressing However, both of those are only small, and we don't use fw_regs a whole lot anyway. The bonuses here include simplicity and improved driver readability. Also, the fact that registers are now referenced by 16-bit absolute addresses (as opposed to 32-bit pseudo addresses) means that over 2kb compiled code size has been shaved off. Includes some touchups and sparse fixes from Ulrich Kunitz. Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_chip.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_chip.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index cc5151683fa1..12dfc0b6efe6 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -84,6 +84,18 @@ static void print_id(struct zd_chip *chip)
84 dev_info(zd_chip_dev(chip), "%s\n", buffer); 84 dev_info(zd_chip_dev(chip), "%s\n", buffer);
85} 85}
86 86
87static zd_addr_t inc_addr(zd_addr_t addr)
88{
89 u16 a = (u16)addr;
90 /* Control registers use byte addressing, but everything else uses word
91 * addressing. */
92 if ((a & 0xf000) == CR_START)
93 a += 2;
94 else
95 a += 1;
96 return (zd_addr_t)a;
97}
98
87/* Read a variable number of 32-bit values. Parameter count is not allowed to 99/* Read a variable number of 32-bit values. Parameter count is not allowed to
88 * exceed USB_MAX_IOREAD32_COUNT. 100 * exceed USB_MAX_IOREAD32_COUNT.
89 */ 101 */
@@ -114,7 +126,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
114 for (i = 0; i < count; i++) { 126 for (i = 0; i < count; i++) {
115 int j = 2*i; 127 int j = 2*i;
116 /* We read the high word always first. */ 128 /* We read the high word always first. */
117 a16[j] = zd_inc_word(addr[i]); 129 a16[j] = inc_addr(addr[i]);
118 a16[j+1] = addr[i]; 130 a16[j+1] = addr[i];
119 } 131 }
120 132
@@ -163,7 +175,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
163 j = 2*i; 175 j = 2*i;
164 /* We write the high word always first. */ 176 /* We write the high word always first. */
165 ioreqs16[j].value = ioreqs[i].value >> 16; 177 ioreqs16[j].value = ioreqs[i].value >> 16;
166 ioreqs16[j].addr = zd_inc_word(ioreqs[i].addr); 178 ioreqs16[j].addr = inc_addr(ioreqs[i].addr);
167 ioreqs16[j+1].value = ioreqs[i].value; 179 ioreqs16[j+1].value = ioreqs[i].value;
168 ioreqs16[j+1].addr = ioreqs[i].addr; 180 ioreqs16[j+1].addr = ioreqs[i].addr;
169 } 181 }
@@ -466,7 +478,8 @@ static int read_values(struct zd_chip *chip, u8 *values, size_t count,
466 478
467 ZD_ASSERT(mutex_is_locked(&chip->mutex)); 479 ZD_ASSERT(mutex_is_locked(&chip->mutex));
468 for (i = 0;;) { 480 for (i = 0;;) {
469 r = zd_ioread32_locked(chip, &v, e2p_addr+i/2); 481 r = zd_ioread32_locked(chip, &v,
482 (zd_addr_t)((u16)e2p_addr+i/2));
470 if (r) 483 if (r)
471 return r; 484 return r;
472 v -= guard; 485 v -= guard;
@@ -953,6 +966,11 @@ static int hw_init(struct zd_chip *chip)
953 return set_beacon_interval(chip, 100); 966 return set_beacon_interval(chip, 100);
954} 967}
955 968
969static zd_addr_t fw_reg_addr(struct zd_chip *chip, u16 offset)
970{
971 return (zd_addr_t)((u16)chip->fw_regs_base + offset);
972}
973
956#ifdef DEBUG 974#ifdef DEBUG
957static int dump_cr(struct zd_chip *chip, const zd_addr_t addr, 975static int dump_cr(struct zd_chip *chip, const zd_addr_t addr,
958 const char *addr_string) 976 const char *addr_string)
@@ -987,9 +1005,11 @@ static int test_init(struct zd_chip *chip)
987 1005
988static void dump_fw_registers(struct zd_chip *chip) 1006static void dump_fw_registers(struct zd_chip *chip)
989{ 1007{
990 static const zd_addr_t addr[4] = { 1008 const zd_addr_t addr[4] = {
991 FW_FIRMWARE_VER, FW_USB_SPEED, FW_FIX_TX_RATE, 1009 fw_reg_addr(chip, FW_REG_FIRMWARE_VER),
992 FW_LINK_STATUS 1010 fw_reg_addr(chip, FW_REG_USB_SPEED),
1011 fw_reg_addr(chip, FW_REG_FIX_TX_RATE),
1012 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
993 }; 1013 };
994 1014
995 int r; 1015 int r;
@@ -1015,7 +1035,8 @@ static int print_fw_version(struct zd_chip *chip)
1015 int r; 1035 int r;
1016 u16 version; 1036 u16 version;
1017 1037
1018 r = zd_ioread16_locked(chip, &version, FW_FIRMWARE_VER); 1038 r = zd_ioread16_locked(chip, &version,
1039 fw_reg_addr(chip, FW_REG_FIRMWARE_VER));
1019 if (r) 1040 if (r)
1020 return r; 1041 return r;
1021 1042
@@ -1095,6 +1116,22 @@ int zd_chip_disable_hwint(struct zd_chip *chip)
1095 return r; 1116 return r;
1096} 1117}
1097 1118
1119static int read_fw_regs_offset(struct zd_chip *chip)
1120{
1121 int r;
1122
1123 ZD_ASSERT(mutex_is_locked(&chip->mutex));
1124 r = zd_ioread16_locked(chip, (u16*)&chip->fw_regs_base,
1125 FWRAW_REGS_ADDR);
1126 if (r)
1127 return r;
1128 dev_dbg_f(zd_chip_dev(chip), "fw_regs_base: %#06hx\n",
1129 (u16)chip->fw_regs_base);
1130
1131 return 0;
1132}
1133
1134
1098int zd_chip_init_hw(struct zd_chip *chip, u8 device_type) 1135int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
1099{ 1136{
1100 int r; 1137 int r;
@@ -1114,7 +1151,7 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
1114 if (r) 1151 if (r)
1115 goto out; 1152 goto out;
1116 1153
1117 r = zd_usb_init_hw(&chip->usb); 1154 r = read_fw_regs_offset(chip);
1118 if (r) 1155 if (r)
1119 goto out; 1156 goto out;
1120 1157
@@ -1294,15 +1331,15 @@ u8 zd_chip_get_channel(struct zd_chip *chip)
1294 1331
1295int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) 1332int zd_chip_control_leds(struct zd_chip *chip, enum led_status status)
1296{ 1333{
1297 static const zd_addr_t a[] = { 1334 const zd_addr_t a[] = {
1298 FW_LINK_STATUS, 1335 fw_reg_addr(chip, FW_REG_LED_LINK_STATUS),
1299 CR_LED, 1336 CR_LED,
1300 }; 1337 };
1301 1338
1302 int r; 1339 int r;
1303 u16 v[ARRAY_SIZE(a)]; 1340 u16 v[ARRAY_SIZE(a)];
1304 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = { 1341 struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = {
1305 [0] = { FW_LINK_STATUS }, 1342 [0] = { fw_reg_addr(chip, FW_REG_LED_LINK_STATUS) },
1306 [1] = { CR_LED }, 1343 [1] = { CR_LED },
1307 }; 1344 };
1308 u16 other_led; 1345 u16 other_led;