resending patch 4/8 as it was reported missing
diff -uprN -X 'netdev-2.6.git#ieee80211/Documentation/dontdiff' 
netdev-2.6.git#ieee80211/drivers/net/wireless/atheros/atheros5212/eeprom.c 
netdev-atheros/drivers/net/wireless/atheros/atheros5212/eeprom.c
--- netdev-2.6.git#ieee80211/drivers/net/wireless/atheros/atheros5212/eeprom.c  
1970-01-01 01:00:00.000000000 +0100
+++ netdev-atheros/drivers/net/wireless/atheros/atheros5212/eeprom.c    
2005-08-05 03:48:36.000000000 +0200
@@ -0,0 +1,501 @@
+/*
+ * 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)
+ *
+ * the original assembly code has been created by Sam Leffler
+ * 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"
+#include "eeprom.h"
+
+/* XXX add calibration info */
+unsigned int get_cal(struct eeprom_info *e, unsigned int val)
+{
+       return 0;
+}
+
+
+/* should be called poll_read. waits some time for a specific value
+ * being read */
+unsigned int ath_timed_read(struct net_device *netdev,
+               unsigned int reg, unsigned int mask,
+               unsigned int val)
+{
+       unsigned int i, tmp;
+       for (i = 0; i < 1000; i++) {
+               tmp = ath_reg_read(netdev, reg) & mask;
+               if ((tmp & mask) == val)
+                       return 1;
+               udelay(15);
+       }
+       
+       printk(KERN_DEBUG"atheros: timed read failing: mask:%x val:%x\n",
+                       mask, val);
+       return 0;
+}
+
+/* read from EEPROM */
+unsigned int eeprom_read(struct net_device *netdev, 
+               unsigned int x, unsigned int *val)
+{
+       
+       ath_reg_write(netdev, 0x6000, x);
+       ath_reg_write(netdev, 0x6008, 1);
+
+       if (!ath_timed_read(netdev, 0x600c, 3, 2))
+               return 0;
+
+       *val = ath_reg_read(netdev, 0x6004) & 0xffff;
+       
+       return 1;       
+}
+
+/* read antenna control stuff while initializing the chipset */
+void eeprom_read_ant_control(struct net_device *netdev, unsigned int reg, 
unsigned int idx)
+{
+       struct atheros_priv *pdata = ieee80211_priv(netdev);
+       struct eeprom_info *e = &pdata->eeinfo;
+       unsigned int val;
+       
+       eeprom_read(netdev, reg++, &val);
+       e->switchval[idx] = (val >> 8) & 0x7f;
+       e->txrx[idx] = (val >> 2) & 0x3f;
+
+       e->antctrl[0][idx] = (val << 4) & 0x3f;
+       e->antctrl[0][idx] |= (val >> 12) & 0x0f;
+       e->antctrl[1][idx] = (val >> 6) & 0x3f;
+       e->antctrl[2][idx] = val & 0x3f;
+
+       eeprom_read(netdev, reg++, &val);
+       e->antctrl[3][idx] = (val >> 10) & 0x3f;
+       e->antctrl[4][idx] = (val >> 4) & 0x3f;
+       e->antctrl[5][idx] = (val << 2) & 0x3f;
+
+       eeprom_read(netdev, reg++, &val);
+       e->antctrl[5][idx] |= (val >> 14) & 3;
+       e->antctrl[6][idx] = (val >> 8) & 0x3f;
+       e->antctrl[7][idx] = (val >> 2) & 0x3f;
+       e->antctrl[8][idx] = (val << 4) & 0x3f;
+
+       eeprom_read(netdev, reg++, &val);
+       e->antctrl[8][idx] |= (val >> 12) & 0xf;
+       e->antctrl[9][idx] = (val >> 6) & 0x3f;
+       e->antctrl[10][idx] = val & 0x3f;
+
+       
+}
+
+/* read wireless mode info from EEPROM 
+ * XXX: this needs splitting to be more readable.
+ * though i have no idea how to do it yet
+ *
+ * this is UGLY UGLY UGLY
+ */
+void eeprom_read_mode(struct net_device *netdev, unsigned int reg, int k)
+{
+       struct atheros_priv *pdata = ieee80211_priv(netdev);
+       struct eeprom_info *e = &pdata->eeinfo;
+       unsigned int val;
+       
+       eeprom_read_ant_control(netdev, reg, k);
+       reg += 4;
+       
+       eeprom_read(netdev, reg++, &val);
+       e->adcsize[k] = (val >> 8) & 0xff;
+
+       switch (k) {
+               case 0:
+                       e->g5_k4 = (val >> 5) & 7;
+                       e->g5_v4 = (val >> 2) & 7;
+                       e->g5_k3 = (val << 1) & 7;
+                       break;
+                       
+               case 1:
+                       e->g2_k1 = (val >> 4) & 7;
+                       e->g2_v1 = val & 7;
+                       break;
+                       
+               case 2:
+                       e->g2_k2g = (val >> 4) & 7;
+                       e->g2_v2g = val & 7;
+                       break;
+       }
+
+       if (k == 0) {
+               eeprom_read(netdev, reg++, &val);
+               e->g5_k3 |= (val >> 15) & 1;
+               e->g5_v3 = (val >> 12) & 7;
+               e->g5_k2 = (val >> 9) & 7;
+               e->g5_v2 = (val >> 6) & 7;
+               e->g5_k1 = (val >> 3) & 7;
+               e->g5_v1 = val & 7;
+       }
+
+       eeprom_read(netdev, reg++, &val);
+       e->txendon[k] = (val >> 8) & 0xff;
+       e->thresh[k] = val & 0xff;
+
+       eeprom_read(netdev, reg++, &val);
+       e->txendoff[k] = (val >> 8) & 0xff;
+       e->txfrmctrl[k] = val & 0xff;
+
+       eeprom_read(netdev, reg++, &val);
+       e->pgasize[k] = (val >> 8) & 0xff;
+       e->noise_floor[k] = val & 0xff;
+
+       if (e->noise_floor[k] & 0x80) {
+               e->noise_floor[k] = 0 - 
+                       ((e->noise_floor[k] ^ 0xff) + 1);
+       }
+
+       eeprom_read(netdev, reg++, &val);
+       e->xlna_gain[k] = (val >> 5) & 0xff;
+       e->xgain[k] = (val >> 1) & 0x0f;
+       e->xpd[k] = val & 1;
+
+       if (e->version >= 0x4000) {
+               switch (k) {
+                       case 0:
+                               e->fixed5 = (val >> 13) & 1;
+                               break;
+                       case 2:
+                               e->fixed2 = (val >> 13) & 1;
+               }
+       }
+
+       if (e->version >= 0x3003) {
+               eeprom_read(netdev, reg++, &val);
+               e->detbkoff[k] = (val >> 6) & 0x7f;
+
+               switch (k) {
+                       case 0:
+                               e->xr5_pwr_limit = val & 0x3f;
+                               break;
+                       case 1:
+                               e->g2_k3[0] = val & 7;
+                               e->g2_v3[0] = (val >> 3) & 7;
+                               break;
+                       case 2:
+                               e->g2_k3[1] = val & 7;
+                               e->g2_v3[1] = (val >> 3) & 7;
+                               break;
+               }
+       }
+       
+       if (e->version >= 0x3004) {
+               e->igain[k] = (val >> 13) & 7;
+               eeprom_read(netdev, reg++, &val);
+               e->igain[k] |= (val << 3) & 0x38;
+               
+               switch (k) {
+                       case 0:
+                               if (e->version >= 0x4000) {
+                                       e->ical[0] = 
+                                               (val >> 8) & 0x3f;
+                                       e->qcal[0] =
+                                               (val >> 3) & 0x1f;
+                               }
+                               break;
+                       case 2:
+                               e->pwr_diff = (val >> 3) & 0xff;
+                               if (e->version >= 0x4006)
+                                       e->scale_14 = 
+                                               (val >> 11) & 0x1f;
+                               break;  
+               }
+       } else {
+               e->igain[k] = 10;
+               e->pwr_diff = 10;
+       }
+       
+       if (e->version >= 0x4000) {
+               switch (k) {
+                       case 0:
+                               if (e->version < 0x4001)
+                                       break;
+                               eeprom_read(netdev,reg++, &val);
+                               e->rxtx_epsilon[0] = val & 0x3f;
+                               break;
+
+                       case 1:
+                               eeprom_read(netdev,reg++,&val);
+                               e->cal11b[0] = 
+                                       get_cal(e, val & 0xff);
+                               e->cal11b[1] = 
+                                       get_cal(e, (val >> 8) & 0xff);
+                               eeprom_read(netdev,reg++,&val);
+                               e->cal11b[2] = 
+                                       get_cal(e, val & 0xff);
+
+                               if (e->version < 0x4001)
+                                       break;
+
+                               e->rxtx_epsilon[1] = 
+                                       (val >> 8) & 0x3f;
+                               break;
+
+                       case 2:
+                               eeprom_read(netdev,reg++,&val);
+                               e->cal11g[0] = 
+                                       get_cal(e, val & 0xff);
+                               e->cal11g[1] = 
+                                       get_cal(e, 
+                                       (val >> 8) & 0xff);
+                               eeprom_read(netdev,reg++,&val);
+                               e->turbo2_pwr_limit =
+                                       val & 0x7f;
+                               e->xr2_pwr_limit = 
+                                       (val >> 7) & 0x3f;
+                               eeprom_read(netdev,reg++,&val);
+                               e->cal11g[2] = 
+                                       get_cal(e, val & 0xff);
+
+                               if (e->version >= 0x4001) {
+                                       e->rxtx_epsilon[2] =
+                                               (val >> 8)&0x3f;
+                               }
+                               eeprom_read(netdev,reg++,&val);
+                               e->ical[1] = (val >> 8) & 0x3f;
+                               e->qcal[1] = (val >> 3) & 0x1f;
+
+                               if (e->version < 0x4002)
+                                       break;
+
+                               eeprom_read(netdev,reg++,&val);
+                               e->pwr_diff = val & 0xff;
+                               break;
+               }
+       }
+}
+
+void eeprom_read_info3_3(struct net_device *netdev)
+{
+       struct atheros_priv *pdata = ieee80211_priv(netdev);
+       struct eeprom_info *e = &pdata->eeinfo;
+       unsigned int val, tmp, i;
+       
+       eeprom_read(netdev, 0xc2, &val);
+       e->disabled_turbo5 = (val >> 15) & 1;
+       e->disabled_turbo2 = (val >> 3) & 1;
+       e->turbo2_pwr_limit = (val >> 4) & 0x7f;
+
+       e->rfkill = (val >> 14) & 1;
+       e->devtyp = (val >> 11) & 1;
+
+       e->mode_a = (val & 1);
+       e->mode_b = (val >> 1) & 1;
+       e->mode_g = (val >> 2) & 1;
+       printk(KERN_DEBUG"atheros: modes [A:%x B:%x G:%x]\n",
+                       e->mode_a, e->mode_b, e->mode_g);
+       
+       eeprom_read(netdev, 0xc3, &val);
+       e->antgain_limit[0] = (char) (val >> 8) & 0xff;
+       e->antgain_limit[1] = (char) (val >> 8);
+
+       if (e->version >= 0x4000) {
+               eeprom_read(netdev, 0xc4, &val);
+               e->mp = (val >> 14) & 3;
+               e->ear = (val & 0xfff);
+               
+               eeprom_read(netdev, 0xc5, &val);
+               e->pwr_start = val & 0xfff;
+               e->clk_32khz = (val >> 14) & val;
+       }
+       
+       eeprom_read_mode(netdev, 0xd4, 0);
+       eeprom_read_mode(netdev, 0xf2, 1);
+       eeprom_read_mode(netdev, 0x10d, 2);
+
+       if (e->version < 0x3003) {
+               eeprom_read(netdev, 0xec, &val);
+               e->g2_k3[0] = val & 7;
+               e->g2_v3[0] = (val >> 3) & 7;
+
+               eeprom_read(netdev, 0xed, &val);
+               e->g2_k3[1] = val & 7;
+               e->g2_v3[1] = (val >> 3) & 7;
+       }
+
+       e->cal.val3 = 4;
+       e->cal.val2 = 1;
+       e->cal.val1 = 1;
+       e->cal.sel = 0;
+
+       tmp = 0x128;
+       for(i = 0; i < e->count; i += 2) {
+               eeprom_read(netdev, tmp++, &val);
+               e->controls[i] = (val >> 8) & 0xff;
+               e->controls[i+1] = val & 0xff;
+       }
+
+       if (e->version <= 0x3002) {
+               e->noise_floor[0] = -54;
+               e->noise_floor[1] = -1;
+               e->noise_floor[2] = -1;
+
+               e->thresh[0] = 15;
+               e->thresh[1] = 28;
+               e->thresh[2] = 28;
+       }
+       
+       return;
+}
+
+unsigned int eeprom_read_info(struct net_device *netdev)
+{
+       struct atheros_priv *pdata = ieee80211_priv(netdev);
+       struct eeprom_info *e = &pdata->eeinfo;
+
+       e->pwr_diff = 15;
+       e->scale_14 = 15;
+
+       printk(KERN_DEBUG"atheros: eeprom version %x\n",
+                       e->version);
+       if (e->version >= 0x3003) {
+               printk(KERN_DEBUG"atheros: >= 3.3\n");
+               eeprom_read_info3_3(netdev);
+               return 1;
+       } else {
+               /* to be added yet XXX
+               eeprom_read_info3(netdev);
+               */
+               return 0;
+       }
+       
+       return 1;
+}
+
+
+/* validates EEPROM checksum */
+unsigned int eeprom_chksum(struct net_device *netdev)
+{
+       unsigned int sum = 0, i, val;
+       
+       for (i = 0; i < 832; i++) {
+               if (!eeprom_read(netdev, 0xc0 + i, &val))
+                       return 0;
+               sum ^= val;
+       }
+
+       if (sum != 0xffff)
+               return 0;
+
+       return 1;
+}
+
+/* initialize EEPROM and prepare the chipset */
+unsigned int eeprom_init(struct net_device *netdev)
+{
+       unsigned int size;
+       unsigned int v;
+       struct atheros_priv *pdata = ieee80211_priv(netdev);
+
+       if (!eeprom_read(netdev, 0xc1, &v)) {
+               printk(KERN_ERR"atheros: eeprom version read failed!\n");
+               return 0;
+       }
+       pdata->eeinfo.version = v;
+
+       printk(KERN_DEBUG"atheros: eeprom_init eeprom version %x\n",
+                       pdata->eeinfo.version);
+       if (pdata->eeinfo.version < 0x3002) {
+               printk(KERN_ERR"atheros: unsupported eeprom version\n");
+               return 0;
+       }
+
+       size = ath_reg_read(netdev, 0x4010);
+       size = (size & 0x18) >> 3;
+
+       if (size != 2) {
+               printk(KERN_ERR"atheros: invalid eeprom size!\n");
+               return 0;
+       }
+       if (eeprom_read(netdev, 0x3f, &v) == 0) {
+               printk(KERN_ERR"atheros: cant read eeprom 3f bit\n");
+               return 0;
+       }
+       pdata->eeinfo.rdonly = v;
+       printk(KERN_DEBUG"atheros: eeprom rdonly flag : %x\n", v);      
+       if (!eeprom_chksum(netdev)) {
+               printk(KERN_ERR"atheros: bad eeprom checksum!\n");
+               return 0;
+       }
+
+       
+       return 1;
+}
+
+/* read chipset capabilities */
+unsigned int eeprom_read_caps(struct net_device *netdev)
+{
+       if (!eeprom_read_info(netdev))
+               return 0;
+
+       /* TODO: read calibration info here */
+       return 1;
+}
+
+/* just as the name says. reads hardware MAC address directly from
+ * EEPROM */
+unsigned int eeprom_read_mac(struct net_device *netdev, unsigned char *mac)
+{
+       unsigned int total = 0, i, val;
+
+       if (mac == NULL)
+               return 0;
+
+       for (i = 0; i < 3; i++) {
+               if (!eeprom_read(netdev, 0x1f - i, &val)) 
+                       return 0;
+               total += val;
+               mac[2*i] = val >> 8;
+               mac[2*i + 1] = val & 0xff;
+       }
+
+       if (total == 0 || total == 3*0xffff)
+               return 0;
+       
+       return 1;
+}
+
diff -uprN -X 'netdev-2.6.git#ieee80211/Documentation/dontdiff' 
netdev-2.6.git#ieee80211/drivers/net/wireless/atheros/atheros5212/eeprom.h 
netdev-atheros/drivers/net/wireless/atheros/atheros5212/eeprom.h
--- netdev-2.6.git#ieee80211/drivers/net/wireless/atheros/atheros5212/eeprom.h  
1970-01-01 01:00:00.000000000 +0100
+++ netdev-atheros/drivers/net/wireless/atheros/atheros5212/eeprom.h    
2005-08-05 03:48:36.000000000 +0200
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef _EEPROM_H
+#define _EEPROM_H
+
+struct cal_info {
+       unsigned short sel;
+       unsigned short val1;
+       unsigned short val2;
+       unsigned short val3;
+};
+
+struct chan_data {
+       unsigned short chan_val;
+       unsigned short lower_limit;
+       unsigned short upper_limit;
+       unsigned short count;
+       unsigned short clk_values[11];
+       short pwr_values[11];
+};
+
+struct power_info {
+       unsigned short pwr1;
+       unsigned short pwr2;
+       unsigned short pwr3;
+       unsigned short pwr4;
+       unsigned short pwr5;
+};
+
+struct power_modes {
+       unsigned short num11a;
+       unsigned short num11b;
+       unsigned short num11g;
+       
+       struct power_info pwr11a[8];
+       struct power_info pwr11b[2];
+       struct power_info pwr11g[3];
+};
+
+struct eestrct {
+       unsigned short val1;
+       unsigned short val2;
+       unsigned char flg;
+};
+
+struct chip_data {
+       unsigned short val1;
+       unsigned short val2;
+       unsigned short vals[4];
+       short vals2[4];
+};
+
+struct chip_chan_data {
+       unsigned short chanval;
+       short pwr_upper_limit;
+       struct chip_data cdata[4];
+};
+
+struct chip_chan_pwr_data {
+       unsigned short *pchans;
+       unsigned short chcount;
+       unsigned short val;
+       struct chip_chan_data *pchandata;
+};
+
+struct eeprom_info {
+       unsigned short version;
+       unsigned short rdonly;
+       unsigned short regdomain;
+       unsigned short devtyp;
+       
+       unsigned short mode_a;
+       unsigned short mode_b;
+       unsigned short mode_g;
+       
+       unsigned short turbo5_pwr_limit;
+       unsigned short turbo2_pwr_limit;
+       
+       unsigned short ext5g;
+       unsigned short xr5_pwr_limit;
+       unsigned short xr2_pwr_limit;
+       
+       unsigned short disabled_turbo5;
+       unsigned short disabled_turbo2;
+       unsigned short rfkill;
+       
+       unsigned char antgain_limit[2];
+
+       unsigned char pwr_diff; /* cck ofdm delta */
+       unsigned short pwr_gain;
+       
+       unsigned char clk_32khz;
+       
+       unsigned short pwr_start;
+       unsigned short fixed5;
+       unsigned short fixed2;
+       unsigned short scale_14;
+       unsigned short mp;
+       unsigned short ear;
+
+
+       unsigned short switchval[3];
+       unsigned short txrx[3];
+       unsigned short txendon[3];
+       unsigned short thresh[3];
+       unsigned short txendoff[3];
+       unsigned short txfrmctrl[3];
+       char adcsize[3];
+       char pgasize[3];
+       unsigned short noise_floor[3];
+       
+       unsigned short xlna_gain[3];
+       unsigned short xgain[3];
+       unsigned short xpd[3];
+       unsigned short antctrl[11][3];
+       unsigned short detbkoff[3];
+       unsigned short igain[3];
+       unsigned short rxtx_epsilon[3]; /* error margin */
+
+       
+       unsigned short g5_k1;
+       unsigned short g5_v1;
+       unsigned short g5_k2;
+       unsigned short g5_v2;
+       unsigned short g5_k3;
+       unsigned short g5_v3;
+       unsigned short g5_k4;
+       unsigned short g5_v4;
+
+       unsigned short g2_k1;
+       unsigned short g2_v1;
+       unsigned short g2_k2g;
+       unsigned short g2_v2g;
+       unsigned short g2_k3[2];
+       unsigned short g2_v3[2];
+       
+       unsigned short count;
+       unsigned short controls[32];
+       
+       unsigned short ical[2];
+       unsigned short qcal[2];
+       
+       unsigned short cal11g[3];
+       unsigned short cal11b[3];
+
+
+       struct cal_info cal;
+
+       unsigned short num_ch5;
+       unsigned short ch_11a[10];
+       struct chan_data chans_11a[10];
+
+       unsigned short num_ch2;
+       unsigned short ch_11g[3];
+       unsigned short ch_11b[3];
+       struct chan_data chans_11g[3];
+       struct chan_data chans_11b[3];
+
+       struct power_modes pmodes;
+
+       struct eestrct rsomething[128];
+       struct chip_chan_pwr_data pvals[3];
+};
+
+unsigned int ath_eeprom_read(struct net_device *,
+               unsigned int x, unsigned int *);
+
+unsigned int ath_timed_read(struct net_device *,
+               unsigned int, unsigned int, unsigned int);
+
+unsigned int eeprom_read(struct net_device *, 
+               unsigned int, unsigned int *);
+
+unsigned int eeprom_init(struct net_device *);
+
+unsigned int eeprom_read_mac(struct net_device *, unsigned char *);
+
+unsigned int eeprom_read_caps(struct net_device *);
+
+
+#endif
+

Reply via email to