aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco/hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/orinoco/hw.c')
-rw-r--r--drivers/net/wireless/orinoco/hw.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index 359652d35e63..e6369242e49c 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -60,8 +60,15 @@ static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
60/* Set priv->firmware type, determine firmware properties 60/* Set priv->firmware type, determine firmware properties
61 * This function can be called before we have registerred with netdev, 61 * This function can be called before we have registerred with netdev,
62 * so all errors go out with dev_* rather than printk 62 * so all errors go out with dev_* rather than printk
63 *
64 * If non-NULL stores a firmware description in fw_name.
65 * If non-NULL stores a HW version in hw_ver
66 *
67 * These are output via generic cfg80211 ethtool support.
63 */ 68 */
64int determine_fw_capabilities(struct orinoco_private *priv) 69int determine_fw_capabilities(struct orinoco_private *priv,
70 char *fw_name, size_t fw_name_len,
71 u32 *hw_ver)
65{ 72{
66 struct device *dev = priv->dev; 73 struct device *dev = priv->dev;
67 hermes_t *hw = &priv->hw; 74 hermes_t *hw = &priv->hw;
@@ -85,6 +92,12 @@ int determine_fw_capabilities(struct orinoco_private *priv)
85 dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n", 92 dev_info(dev, "Hardware identity %04x:%04x:%04x:%04x\n",
86 nic_id.id, nic_id.variant, nic_id.major, nic_id.minor); 93 nic_id.id, nic_id.variant, nic_id.major, nic_id.minor);
87 94
95 if (hw_ver)
96 *hw_ver = (((nic_id.id & 0xff) << 24) |
97 ((nic_id.variant & 0xff) << 16) |
98 ((nic_id.major & 0xff) << 8) |
99 (nic_id.minor & 0xff));
100
88 priv->firmware_type = determine_firmware_type(&nic_id); 101 priv->firmware_type = determine_firmware_type(&nic_id);
89 102
90 /* Get the firmware version */ 103 /* Get the firmware version */
@@ -135,8 +148,9 @@ int determine_fw_capabilities(struct orinoco_private *priv)
135 case FIRMWARE_TYPE_AGERE: 148 case FIRMWARE_TYPE_AGERE:
136 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, 149 /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
137 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ 150 ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
138 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 151 if (fw_name)
139 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); 152 snprintf(fw_name, fw_name_len, "Lucent/Agere %d.%02d",
153 sta_id.major, sta_id.minor);
140 154
141 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; 155 firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
142 156
@@ -185,8 +199,8 @@ int determine_fw_capabilities(struct orinoco_private *priv)
185 tmp[SYMBOL_MAX_VER_LEN] = '\0'; 199 tmp[SYMBOL_MAX_VER_LEN] = '\0';
186 } 200 }
187 201
188 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 202 if (fw_name)
189 "Symbol %s", tmp); 203 snprintf(fw_name, fw_name_len, "Symbol %s", tmp);
190 204
191 priv->has_ibss = (firmver >= 0x20000); 205 priv->has_ibss = (firmver >= 0x20000);
192 priv->has_wep = (firmver >= 0x15012); 206 priv->has_wep = (firmver >= 0x15012);
@@ -224,9 +238,9 @@ int determine_fw_capabilities(struct orinoco_private *priv)
224 * different and less well tested */ 238 * different and less well tested */
225 /* D-Link MAC : 00:40:05:* */ 239 /* D-Link MAC : 00:40:05:* */
226 /* Addtron MAC : 00:90:D1:* */ 240 /* Addtron MAC : 00:90:D1:* */
227 snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, 241 if (fw_name)
228 "Intersil %d.%d.%d", sta_id.major, sta_id.minor, 242 snprintf(fw_name, fw_name_len, "Intersil %d.%d.%d",
229 sta_id.variant); 243 sta_id.major, sta_id.minor, sta_id.variant);
230 244
231 firmver = ((unsigned long)sta_id.major << 16) | 245 firmver = ((unsigned long)sta_id.major << 16) |
232 ((unsigned long)sta_id.minor << 8) | sta_id.variant; 246 ((unsigned long)sta_id.minor << 8) | sta_id.variant;
@@ -245,7 +259,8 @@ int determine_fw_capabilities(struct orinoco_private *priv)
245 } 259 }
246 break; 260 break;
247 } 261 }
248 dev_info(dev, "Firmware determined as %s\n", priv->fw_name); 262 if (fw_name)
263 dev_info(dev, "Firmware determined as %s\n", fw_name);
249 264
250 return 0; 265 return 0;
251} 266}
@@ -1013,7 +1028,7 @@ int orinoco_clear_tkip_key(struct orinoco_private *priv, int key_idx)
1013} 1028}
1014 1029
1015int __orinoco_hw_set_multicast_list(struct orinoco_private *priv, 1030int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
1016 struct dev_addr_list *mc_list, 1031 struct net_device *dev,
1017 int mc_count, int promisc) 1032 int mc_count, int promisc)
1018{ 1033{
1019 hermes_t *hw = &priv->hw; 1034 hermes_t *hw = &priv->hw;
@@ -1034,24 +1049,16 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
1034 * group address if either we want to multicast, or if we were 1049 * group address if either we want to multicast, or if we were
1035 * multicasting and want to stop */ 1050 * multicasting and want to stop */
1036 if (!promisc && (mc_count || priv->mc_count)) { 1051 if (!promisc && (mc_count || priv->mc_count)) {
1037 struct dev_mc_list *p = mc_list; 1052 struct dev_mc_list *p;
1038 struct hermes_multicast mclist; 1053 struct hermes_multicast mclist;
1039 int i; 1054 int i = 0;
1040 1055
1041 for (i = 0; i < mc_count; i++) { 1056 netdev_for_each_mc_addr(p, dev) {
1042 /* paranoia: is list shorter than mc_count? */ 1057 if (i == mc_count)
1043 BUG_ON(!p); 1058 break;
1044 /* paranoia: bad address size in list? */ 1059 memcpy(mclist.addr[i++], p->dmi_addr, ETH_ALEN);
1045 BUG_ON(p->dmi_addrlen != ETH_ALEN);
1046
1047 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
1048 p = p->next;
1049 } 1060 }
1050 1061
1051 if (p)
1052 printk(KERN_WARNING "%s: Multicast list is "
1053 "longer than mc_count\n", priv->ndev->name);
1054
1055 err = hermes_write_ltv(hw, USER_BAP, 1062 err = hermes_write_ltv(hw, USER_BAP,
1056 HERMES_RID_CNFGROUPADDRESSES, 1063 HERMES_RID_CNFGROUPADDRESSES,
1057 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), 1064 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),