Skip to contentSkip to conversation

atheros driver (7/8)

PATCH Mateusz Berezecki 1 participant 1 message Aug 5, 2005

Subsystems (3)
lore
Share & tools
lore
#0 lore raw
drivers/net/wireless/atheros/atheros5212/keys.c +268 -0
diff -uprN -X 'netdev-2.6.git#ieee80211/Documentation/dontdiff' netdev-2.6.git#ieee80211/drivers/net/wireless/atheros/atheros5212/keys.c netdev-atheros/drivers/net/wireless/atheros/atheros5212/keys.c
@@ -0,0 +1,268 @@
+/*
+ * All the work was created by reverse engineering and porting
+ * for interoperability. The creator is Mateusz Berezecki,
+ * unless explicitly marked ( some parts are derived
+ * from GPL'ed parts of madwifi project located at http://madwifi.sf.net)
+ *
+ * derived or copied parts of code licensed under
+ * dual GPL/BSD license
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ * 
+ * rest of the code has been reversed by me and is under copyright too
+ * Copyright (C) 2005  Mateusz Berezecki
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+
+#include <net/ieee80211.h>
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+#include "atheros_id.h"
+#include "atheros_dev.h"
+#include "atheros_defs.h"
+//#include "atheros_devops.h"
+//#include "atheros_regops.h"
+#include "atheros_registers.h"
+#include "atheros.h"
+
+
+unsigned int ath_keycache_valid(struct net_device *netdev,
+		unsigned short entry)
+{
+	struct atheros_priv *pdata;
+	unsigned int val;
+	
+	pdata = ieee80211_priv(netdev);
+	
+	if (entry > pdata->max_keycache)
+		return 0;
+	
+	val = ath_reg_read(netdev, 0x8800 + entry * 32 + 28);
+
+	if (val & 0x8000)
+		return 1;
+	
+	return 0;
+}
+
+unsigned int ath_reset_keycache(struct net_device *netdev,
+		unsigned short entry)
+{
+	struct atheros_priv *pdata;
+	unsigned int keytype;
+	
+	pdata = ieee80211_priv(netdev);
+	
+	if (entry > pdata->keycache_size)
+		return 0;
+
+	keytype = ath_reg_read(netdev, (entry * 32) + 0x8814);
+
+	ath_reg_write(netdev, (entry * 32) + 0x8800, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x8804, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x8808, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x880c, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x8810, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x8814, 7);
+	ath_reg_write(netdev, (entry * 32) + 0x8818, 0);
+	ath_reg_write(netdev, (entry * 32) + 0x881c, 0);
+	
+	if (keytype != 4)
+		return 1;
+
+	if (!pdata->ext_keycache)
+		return 1;
+
+	ath_reg_write(netdev, ((entry + 64) * 32) + 0x8800, 0);
+	ath_reg_write(netdev, ((entry + 64) * 32) + 0x8804, 0);
+	ath_reg_write(netdev, ((entry + 64) * 32) + 0x8808, 0);
+	ath_reg_write(netdev, ((entry + 64) * 32) + 0x880c, 0);
+
+	return 1;
+}
+
+unsigned int ath_set_keycache_entry_mac(struct net_device *netdev,
+		unsigned short entry, unsigned char *mac)
+{
+	struct atheros_priv *pdata;
+	unsigned int mac1, mac2;
+	
+	pdata = ieee80211_priv(netdev);
+
+	if (entry > pdata->max_keycache)
+		return 0;
+
+	if (mac == NULL) {
+		mac1 = 0;
+		mac2 = 0;
+	} else {
+		mac1  = mac[5] << 8;
+		mac1 |= mac[4];
+		
+		mac2  = mac[3] << 24;
+		mac2 |= mac[2] << 16;
+		mac2 |= mac[1] << 8;
+		mac2 |= mac[0];
+		
+		mac2 = mac2 >> 1;
+		mac2 |= ((mac1 & 1)<< 31);
+		
+		mac1 = mac1 >> 1;
+	}
+
+	ath_reg_write(netdev, (entry * 32) + 0x8800 + 24, mac2);
+	ath_reg_write(netdev, (entry * 32) + 0x8800 + 28, mac1 | 0x80);
+
+	return 1;
+}
+
+unsigned int ath_set_keycache_entry(struct net_device *netdev,
+		unsigned short entry, struct keyval *kv,
+		unsigned char *mac, int num)
+{
+	int flg = (num == 1) ? 0xffffffff : 0;
+	int cipher_opt;
+	int newentry;
+	struct atheros_priv *pdata = ieee80211_priv(netdev);
+	unsigned int part1, part2, part3, part4, part5;
+
+
+	flg &= 0xaaaaaaaa;
+
+	if (entry > pdata->max_keycache)
+		return 0;
+
+	switch (kv->kv_type) {
+		case CIPHER_AES_OCB:
+			cipher_opt = 5;
+			break;
+
+		case CIPHER_AES_CCM:
+			/* fixme TODO FIXME */
+			return 0;
+//			break;
+
+		case CIPHER_TKIP:
+			cipher_opt = 4;
+
+			if ((entry + 0x40) > pdata->max_keycache)
+				return 0;
+
+			break;
+
+		case CIPHER_WEP:
+			if (kv->kv_len <= 4)
+				return 0;
+			
+			cipher_opt = 0;
+
+			if (kv->kv_len <= 5) 
+				break;
+
+			cipher_opt = (kv->kv_len == 14) ? 0 : 0xffffffff;
+			cipher_opt &= 0xfffffffe;
+			cipher_opt += 3;
+
+			break;
+
+		case CIPHER_CLR:
+			cipher_opt = 7;
+			break;
+			
+		default:
+			return 0;
+	}
+
+	part1 = (kv->kv_val[0] | (kv->kv_val[1] << 8) | 
+		(kv->kv_val[2] << 16) | (kv->kv_val[3] << 24)) ^ flg;
+
+
+	part2 = ((kv->kv_val[4] | (kv->kv_val[5] << 8)) ^ flg) & 0xffff;
+	
+	part4 = ((kv->kv_val[6] | (kv->kv_val[7] << 8) |
+	  (kv->kv_val[8] << 16) | (kv->kv_val[9] << 24)) ^ flg);
+
+	part3 = ((kv->kv_val[10] | (kv->kv_val[11] << 8)) ^ flg) & 0xffff;
+
+	part5 = (kv->kv_val[12] | (kv->kv_val[13] << 8) | 
+	      (kv->kv_val[14] << 16) | (kv->kv_val[15] << 24)) ^ flg;
+
+	if (kv->kv_len <= 13)
+		 part5 &= 0xff;
+
+
+	/* if statement needs fixing */
+	if (cipher_opt == 4 && pdata->turbo != 0) {
+		newentry = (entry << 5);
+
+		ath_reg_write(netdev, 0x8800 + (entry << 5), ~part1);
+		ath_reg_write(netdev, 0x8804 + newentry,  ~part2);
+		ath_reg_write(netdev, 0x8808 + newentry, part4);
+		ath_reg_write(netdev, 0x880c + newentry, part3);
+		ath_reg_write(netdev, 0x8810 + newentry, part5);
+		ath_reg_write(netdev, 0x8814 + newentry, 4);
+
+		ath_set_keycache_entry_mac(netdev, entry, mac);
+
+		ath_reg_write(netdev, 0x8800 + ((entry + 0x40) << 5), 
+			(kv->kv_mic[0] | (kv->kv_mic[1] << 8) |
+			(kv->kv_mic[2] << 16) | (kv->kv_mic[3] << 24)));
+		
+		ath_reg_write(netdev, 0x8804 + ((entry + 0x40) << 5), 0);
+		
+		ath_reg_write(netdev, 0x8808 + ((entry + 0x40) << 5), 
+			( kv->kv_mic[4] | (kv->kv_mic[5] << 8) |
+			  (kv->kv_mic[6] << 16) | (kv->kv_mic[7] << 24) ) );
+		
+		ath_reg_write(netdev, 0x880c + ((entry + 0x40) << 5), 0);
+		ath_reg_write(netdev, 0x8810 + ((entry + 0x40) << 5), 0);
+		ath_reg_write(netdev, 0x8814 + ((entry + 0x40) << 5), 7);
+		ath_reg_write(netdev, 0x8818 + ((entry + 0x40) << 5), 0);
+		ath_reg_write(netdev, 0x881c + ((entry + 0x40) << 5), 0);
+		
+		ath_reg_write(netdev, 0x8800 + newentry, part1);
+		ath_reg_write(netdev, 0x8800 + newentry, part2);
+
+		return 1;
+	} else {
+		ath_reg_write(netdev, 0x8800 + (entry << 5), part1);
+		ath_reg_write(netdev, 0x8804 + (entry << 5), part2);
+		ath_reg_write(netdev, 0x8808 + (entry << 5), part4);
+		ath_reg_write(netdev, 0x880c + (entry << 5), part3);
+		ath_reg_write(netdev, 0x8810 + (entry << 5), part5);
+		ath_reg_write(netdev, 0x8814 + (entry << 5), cipher_opt);
+
+		ath_set_keycache_entry_mac(netdev, entry, mac);
+		return 1;
+	}
+		
+	return 0;
+}
+unsigned int ath_get_keycache_size(struct net_device *netdev)
+{
+	return 128;
+}
+
drivers/net/wireless/atheros/atheros5212/mode_tables.c +309 -0

309 lines not on this page · raw message

drivers/net/wireless/atheros/atheros5212/mode_tables.h +60 -0

60 lines not on this page · raw message

_______________________________________________
Kernel-mentors mailing list
[email protected]
http://selenic.com/mailman/listinfo/kernel-mentors